From 9747149d2b7497e2a266c5c77e1310477fb61c6f Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 12:37:34 +0200 Subject: [PATCH 001/740] Use try-with-resources to close file resources This is a fix for a FindBugs issue warning about unclosed files. --- .../com/redhat/mqe/jms/ConnectionManager.java | 10 ++++-- .../com/redhat/mqe/lib/ConnectionManager.java | 4 ++- .../java/com/redhat/mqe/lib/SenderClient.java | 34 ++++++++----------- .../main/java/com/redhat/mqe/lib/Utils.java | 7 ++-- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java index 8042bfde..a4f03e83 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java @@ -25,6 +25,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Properties; import javax.jms.*; import javax.naming.Context; @@ -65,12 +66,15 @@ public class ConnectionManager { String jndiFilePath; if ((jndiFilePath = System.getProperty(EXTERNAL_JNDI_PROPERTY)) != null) { // load property file from an absolute path to the file - FileInputStream fileInputStream = new FileInputStream(new File(jndiFilePath)); - props.load(fileInputStream); + try (FileInputStream fileInputStream = new FileInputStream(new File(jndiFilePath))) { + props.load(fileInputStream); + } } else { // fallback to use resources/jndi.properties file jndiFilePath = "/jndi.properties"; - props.load(this.getClass().getResourceAsStream(jndiFilePath)); + try (InputStream inputStream = this.getClass().getResourceAsStream(jndiFilePath)) { + props.load(inputStream); + } } if (connectionFactory.contains("://")) { // override connectionFactory by this option in jndi/properties diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/ConnectionManager.java b/jmslib/src/main/java/com/redhat/mqe/lib/ConnectionManager.java index 9ecf003c..3ea61a3f 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/ConnectionManager.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/ConnectionManager.java @@ -160,7 +160,9 @@ protected void setInitialContext(String userConnectionFactory) { String jndiFilePath; if ((jndiFilePath = System.getProperty(EXTERNAL_JNDI_PROPERTY)) != null) { // load property file from an absolute path to the file - properties.load(new FileInputStream(jndiFilePath)); + try (FileInputStream stream = new FileInputStream(jndiFilePath)) { + properties.load(stream); + } } else { ClassLoader classloader = Thread.currentThread().getContextClassLoader(); String JNDIFile; diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java b/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java index 93336876..49dd6c9c 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java @@ -565,27 +565,23 @@ static void createMessageContent(ClientOptions senderOptions) { */ private static byte[] readBinaryContentFromFile(String binaryFileName) { File binaryFile = new File(binaryFileName); - byte[] bytesOut = null; - if (binaryFile.canRead()) { - bytesOut = new byte[(int) binaryFile.length()]; - try { - try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(binaryFile))) { - int totalBytesRead = 0; - while (totalBytesRead < bytesOut.length) { - int bytesRemaining = bytesOut.length - totalBytesRead; - //input.read() returns -1, 0, or more : - int bytesRead = bis.read(bytesOut, totalBytesRead, bytesRemaining); - if (bytesRead > 0) { - totalBytesRead = totalBytesRead + bytesRead; - } - } + try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(binaryFile))) { + byte[] bytesOut = new byte[(int) binaryFile.length()]; + int totalBytesRead = 0; + while (totalBytesRead < bytesOut.length) { + int bytesRemaining = bytesOut.length - totalBytesRead; + //input.read() returns -1, 0, or more : + int bytesRead = bis.read(bytesOut, totalBytesRead, bytesRemaining); + if (bytesRead > 0) { + totalBytesRead = totalBytesRead + bytesRead; } - } catch (IOException e) { - e.printStackTrace(); } + LOG.error("ToSend=" + new String(bytesOut)); + return bytesOut; + } catch (IOException e) { + e.printStackTrace(); } - LOG.error("ToSend=" + new String(bytesOut)); - return bytesOut; + return null; } @@ -594,7 +590,7 @@ private static byte[] readBinaryContentFromFile(String binaryFileName) { * as a string representation of all lines. * * @param path path to file to read input from - * @return the concatenad + * @return the concatenated lines */ private static String readContentFromFile(String path) { StringBuilder fileContent = new StringBuilder(); diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java b/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java index 7ebda673..83e0ffa3 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java @@ -343,14 +343,15 @@ public static void writeBinaryContentToFile(String filePath, Message message, in } LOG.debug("Write binary content to file '" + writeBinaryFile.getPath() + "'."); - FileOutputStream fos = new FileOutputStream(writeBinaryFile); if (message instanceof BytesMessage) { BytesMessage bm = (BytesMessage) message; readByteArray = new byte[(int) bm.getBodyLength()]; bm.reset(); // added to be able to read message content bm.readBytes(readByteArray); - fos.write(readByteArray); - fos.close(); + try (FileOutputStream fos = new FileOutputStream(writeBinaryFile)) { + fos.write(readByteArray); + fos.close(); + } } else if (message instanceof StreamMessage) { LOG.debug("Writing StreamMessage to"); From 0c7711e349aba8f84b0bac8b0b779c6555376b1c Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 12:39:22 +0200 Subject: [PATCH 002/740] Replace static fields with instance fields This is a fix for FindBugs issue. Static fields are to be generally avoided, unless there is a good reason. Which there is not. --- .../main/java/com/redhat/mqe/jms/ConnectionManager.java | 2 +- .../src/main/java/com/redhat/mqe/lib/ConnectorClient.java | 4 ++-- jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java | 8 ++++---- jmslib/src/main/java/com/redhat/mqe/lib/Utils.java | 6 ++++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java index a4f03e83..a3805537 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java @@ -34,7 +34,7 @@ public class ConnectionManager { private ConnectionFactory factory; - private static Context context; + private Context context; private Destination destination; private Connection connection; private String customConnectionFactory = "connectionfactory.amqFactory"; diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/ConnectorClient.java b/jmslib/src/main/java/com/redhat/mqe/lib/ConnectorClient.java index cf914b94..67b677af 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/ConnectorClient.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/ConnectorClient.java @@ -32,8 +32,8 @@ public class ConnectorClient extends CoreClient { private ClientOptions connectorOptions; - private static int connectionsOpened = 0; - private static Logger LOG_CLEAN = LoggerFactory.getLogger(MessageFormatter.class); + private int connectionsOpened = 0; + private Logger LOG_CLEAN = LoggerFactory.getLogger(MessageFormatter.class); public ConnectorClient(String[] arguments, ConnectionManagerFactory connectionManagerFactory, MessageFormatter messageFormatter, ClientOptions options) { this.connectionManagerFactory = connectionManagerFactory; diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java b/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java index 49dd6c9c..2bf03d62 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/SenderClient.java @@ -39,11 +39,11 @@ */ public class SenderClient extends CoreClient { private ClientOptions senderOptions; - protected static List content; - private static boolean isEmptyMessage = false; + protected List content; + private boolean isEmptyMessage = false; private boolean userMessageCounter = false; private String userMessageCounterText; - private static byte[] binaryMessageData; + private byte[] binaryMessageData; static final String QPID_SUBJECT = "qpid.subject"; static final String AMQ_SUBJECT = "JMS_AMQP_Subject"; static final String QPID_USERID = ""; // TODO @@ -521,7 +521,7 @@ ClientOptions getClientOptions() { * @param senderOptions use provided input option * @return list of created options with at least one value */ - static void createMessageContent(ClientOptions senderOptions) { + private void createMessageContent(ClientOptions senderOptions) { List contentList = new ArrayList<>(); String globalContentType = null; // Set global content value diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java b/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java index 83e0ffa3..eea6871a 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/Utils.java @@ -32,6 +32,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Collections; import java.util.List; @@ -42,8 +43,9 @@ public class Utils { private static Logger LOG = LoggerFactory.getLogger(Utils.class); - public static List> CLASSES = Arrays.asList( - new Class[]{Integer.class, Long.class, Float.class, Double.class, Boolean.class, String.class}); + + public static final List> CLASSES = Collections.unmodifiableList(Arrays.asList( + Integer.class, Long.class, Float.class, Double.class, Boolean.class, String.class)); // todo Short.class, Byte.class ? /** From 8fa213e03a9214884dfd32057f115fbcfb1595be Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 20:45:43 +0200 Subject: [PATCH 003/740] Add more tests to increase coverage --- tests/src/test/kotlin/AbstractMainTest.kt | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/src/test/kotlin/AbstractMainTest.kt b/tests/src/test/kotlin/AbstractMainTest.kt index 57d1b1d3..7e287b27 100644 --- a/tests/src/test/kotlin/AbstractMainTest.kt +++ b/tests/src/test/kotlin/AbstractMainTest.kt @@ -152,6 +152,47 @@ abstract class AbstractMainTest { } } + @Test + fun sendAndReceiveSingleMessageUsingCredentials() { + val senderParameters = + "sender --log-msgs dict --broker $brokerUrl --address $address --conn-username admin --conn-password admin --count 1".split(" ").toTypedArray() + val receiverParameters = + "receiver --log-msgs dict --broker $brokerUrl --address $address --conn-username admin --conn-password admin --count 1".split(" ").toTypedArray() + assertTimeoutPreemptively(Duration.ofSeconds(10)) { + print("Sending: ") + main(senderParameters) + print("Receiving: ") + main(receiverParameters) + } + } + + @Test + fun sendBrowseAndReceiveSingleMessageWithEmptySelector() { + val senderParameters = + "sender --log-msgs dict --broker $brokerUrl --address $address --count 1".split(" ").toTypedArray() + val receiverParameters = + "receiver --log-msgs dict --broker $brokerUrl --address $address --msg-selector '' --count 1".split(" ").toTypedArray() + assertTimeoutPreemptively(Duration.ofSeconds(10)) { + print("Sending: ") + main(senderParameters) + print("Browsing: ") + main(receiverParameters + "--recv-browse true".split(" ").toTypedArray()) + print("Receiving: ") + main(receiverParameters) + } + } + + @Test + fun sendSingleMessageWithoutProtocolInBrokerUrl() { + val brokerUrl = brokerUrl.substringAfter(":") + val senderParameters = + "sender --log-msgs dict --broker $brokerUrl --address $address --count 1".split(" ").toTypedArray() + assertTimeoutPreemptively(Duration.ofSeconds(10)) { + print("Sending: ") + main(senderParameters) + } + } + @ParameterizedTest @CsvFileSource(resources = arrayOf("/receiver.csv")) fun sendAndReceiveWithAllReceiverCLISwitches(receiverDynamicOptions: String) { From 44407f3ee04a2bcfade4821ce7b15fedb9be6939 Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Tue, 10 Oct 2017 11:12:24 +0200 Subject: [PATCH 004/740] Switch to using activemq-artemis upstream snapshot in .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d9aa66eb..098420a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,8 @@ env: script: # https://docs.travis-ci.com/user/docker/ - - docker pull enkeys/alpine-openjdk-amq7-snapshot - - docker run --rm -v`pwd`/scripts:/mnt -p 5672:5672 -p 61616:61616 --entrypoint ash enkeys/alpine-openjdk-amq7-snapshot /mnt/entrypoint.sh amq7-server & + - docker pull jdanekrh/docker-alpine-openjdk-artemis-snapshot + - docker run --rm -v`pwd`/scripts:/mnt -p 5672:5672 -p 61616:61616 --entrypoint ash jdanekrh/docker-alpine-openjdk-artemis-snapshot /mnt/entrypoint.sh amq7-server & - sleep 10 - mvn clean verify From 12b3dec39f6580f318edcff754f55dbc3e2bba31 Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 14:40:40 +0200 Subject: [PATCH 005/740] Fix username url property for artemis-jms-client The way the cli works is that username is specified in both the connection url as well as in the createSession call. It is enough to get it right in the createSession call, which is what was happening. The library does not error on unrecognized url parameters. --- .../java/com/redhat/mqe/acc/AccClientOptionManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java index 870b3a3a..0997b669 100644 --- a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java +++ b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java @@ -35,8 +35,10 @@ class AccClientOptionManager extends ClientOptionManager { // artemis-core-client/org/apache/activemq/artemis/core/protocol/core/impl/RemotingConnectionImpl.java // tests/activemq5-unit-tests/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java // artemis-jms-client/src/test/java/org/apache/activemq/artemis/uri/ConnectionFactoryURITest.java - CONNECTION_TRANSLATION_MAP.put(ClientOptions.USERNAME, "jms.userName"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.PASSWORD, "jms.password"); + + // artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java + CONNECTION_TRANSLATION_MAP.put(ClientOptions.USERNAME, "user"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.PASSWORD, "password"); CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_VHOST, ""); CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_MECHS, ""); CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_LAYER, ""); From ae8eb15cce0f937ef3dc065ef1febebfb83ede0b Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 14:22:57 +0200 Subject: [PATCH 006/740] New test for MessageFormatter empty BytesMessage --- .../src/test/kotlin/MessageFormatterTest.kt | 26 ++++++++++ .../src/test/kotlin/MessageFormatterTest.kt | 27 ++++++++++ tests/pom.xml | 14 +++++ .../mqe/lib/AbstractMessageFormatterTest.kt | 52 +++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 cli-activemq/src/test/kotlin/MessageFormatterTest.kt create mode 100644 cli-qpid-jms/src/test/kotlin/MessageFormatterTest.kt create mode 100644 tests/src/test/kotlin/com/redhat/mqe/lib/AbstractMessageFormatterTest.kt diff --git a/cli-activemq/src/test/kotlin/MessageFormatterTest.kt b/cli-activemq/src/test/kotlin/MessageFormatterTest.kt new file mode 100644 index 00000000..8d9f3b25 --- /dev/null +++ b/cli-activemq/src/test/kotlin/MessageFormatterTest.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.redhat.mqe.lib.AbstractMessageFormatterTest +import org.apache.activemq.command.ActiveMQBytesMessage +import javax.jms.BytesMessage + +class AocMessageFormatterTest : AbstractMessageFormatterTest() { + override fun getBytesMessage(): BytesMessage = ActiveMQBytesMessage() +} diff --git a/cli-qpid-jms/src/test/kotlin/MessageFormatterTest.kt b/cli-qpid-jms/src/test/kotlin/MessageFormatterTest.kt new file mode 100644 index 00000000..1fb3fd5d --- /dev/null +++ b/cli-qpid-jms/src/test/kotlin/MessageFormatterTest.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.redhat.mqe.lib.AbstractMessageFormatterTest +import org.apache.qpid.jms.message.JmsBytesMessage +import org.apache.qpid.jms.provider.amqp.message.AmqpJmsBytesMessageFacade +import javax.jms.BytesMessage + +class AacMessageFormatterTest : AbstractMessageFormatterTest() { + override fun getBytesMessage(): BytesMessage = JmsBytesMessage(AmqpJmsBytesMessageFacade()) +} diff --git a/tests/pom.xml b/tests/pom.xml index 93b89327..f5270af0 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -35,6 +35,20 @@ + + + + org.apache.geronimo.specs + geronimo-jms_2.0_spec + provided + + + + com.redhat.cli-java + jmslib + + + diff --git a/tests/src/test/kotlin/com/redhat/mqe/lib/AbstractMessageFormatterTest.kt b/tests/src/test/kotlin/com/redhat/mqe/lib/AbstractMessageFormatterTest.kt new file mode 100644 index 00000000..c95c6ece --- /dev/null +++ b/tests/src/test/kotlin/com/redhat/mqe/lib/AbstractMessageFormatterTest.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.redhat.mqe.lib + +import com.google.common.truth.Truth.assertThat +import org.junit.jupiter.api.Test +import javax.jms.BytesMessage +import javax.jms.Message + +class Formatter : MessageFormatter() { + override fun printMessageBodyAsText(message: Message?) { + TODO("not implemented") + } + + override fun printMessageAsDict(msg: Message?) { + TODO("not implemented") + } + + override fun printMessageAsInterop(msg: Message?) { + TODO("not implemented") + } +} + +abstract class AbstractMessageFormatterTest { + private val formatter = Formatter() + + abstract fun getBytesMessage(): BytesMessage + + @Test + fun formatContentOfBytesMessage_empty() { + val bytesMessage = getBytesMessage() + bytesMessage.reset() + assertThat(formatter.formatContent(bytesMessage).toString()).isEqualTo("None") + } +} From 5442422937970f2542cf5efd61b2e85e31b07b59 Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 20:44:47 +0200 Subject: [PATCH 007/740] New parametrized connector PICT tests --- cli-activemq/src/test/kotlin/MainTest.kt | 29 +++++++++++++ cli-artemis-jms/src/test/kotlin/MainTest.kt | 48 +++++++++++++++++++++ cli-qpid-jms/src/test/kotlin/MainTest.kt | 40 +++++++++++++++++ tests/connector.pict | 7 +++ tests/generate_csv_from_pict.py | 5 +-- tests/src/test/kotlin/AbstractMainTest.kt | 14 ++++++ tests/src/test/resources/connector.csv | 9 ++++ 7 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 tests/connector.pict create mode 100644 tests/src/test/resources/connector.csv diff --git a/cli-activemq/src/test/kotlin/MainTest.kt b/cli-activemq/src/test/kotlin/MainTest.kt index fef815cc..4bbed4a0 100644 --- a/cli-activemq/src/test/kotlin/MainTest.kt +++ b/cli-activemq/src/test/kotlin/MainTest.kt @@ -76,6 +76,35 @@ class AocMainTest : AbstractMainTest() { --msg-ttl 10000 --msg-user-id aMsgUserId --property-type String +""".split(" ", "\n").toTypedArray() + + override val connectorAdditionalOptions = + """ +--conn-tcp-traffic-class 2 +--conn-prefix-packet-size-ena false +--conn-async-send true +--conn-cache-ena false +--conn-cache-size 1 +--conn-clientid aClientId +--conn-close-timeout 1000 +--conn-heartbeat 1000 +--conn-max-frame-size 4096 +--conn-prefetch 1 +--conn-prefetch-browser 1 +--conn-prefetch-queue 1 +--conn-prefetch-topic 1 +--conn-prefetch-topic-dur 1 +--conn-redeliveries-max 1 +--conn-server-stack-trace-ena false +--conn-sync-send true +--conn-tcp-buf-size-recv 1 +--conn-tcp-buf-size-send 1 +--conn-tcp-conn-timeout 1000 +--conn-tcp-keep-alive true +--conn-tcp-no-delay false +--conn-tcp-sock-linger 1000 +--conn-tcp-sock-timeout 1000 +--conn-tight-encoding-ena false """.split(" ", "\n").toTypedArray() override fun main(args: Array) = Main.main(args) diff --git a/cli-artemis-jms/src/test/kotlin/MainTest.kt b/cli-artemis-jms/src/test/kotlin/MainTest.kt index 42428099..3c2248d6 100644 --- a/cli-artemis-jms/src/test/kotlin/MainTest.kt +++ b/cli-artemis-jms/src/test/kotlin/MainTest.kt @@ -84,6 +84,54 @@ class AccMainTest : AbstractMainTest() { --msg-ttl 10000 --msg-user-id aMsgUserId --property-type String +""".split(" ", "\n").toTypedArray() + + override val connectorAdditionalOptions = + """ +--conn-async-acks true +--conn-async-send true +--conn-auth-mechanisms anonymous +--conn-auth-sasl false +--conn-cache-ena false +--conn-cache-size 1 +--conn-clientid aClientId +--conn-clientid-prefix aClientIdPrefix +--conn-close-timeout 1000 +--conn-conn-timeout 1000 +--conn-connid-prefix aConnIdPrefix +--conn-heartbeat 1000 +--conn-local-msg-priority true +--conn-max-frame-size 4096 +--conn-prefetch 1 +--conn-prefetch-browser 1 +--conn-prefetch-queue 1 +--conn-prefetch-topic 1 +--conn-prefetch-topic-dur 1 +--conn-prefix-packet-size-ena false +--conn-queue-prefix aQueuePrefix +--conn-reconnect true +--conn-reconnect-backoff false +--conn-reconnect-backoff-multiplier 1 +--conn-reconnect-initial-delay 1 +--conn-reconnect-interval 1000 +--conn-reconnect-limit 1000 +--conn-reconnect-start-limit 1000 +--conn-reconnect-timeout 1000 +--conn-reconnect-warn-attempts 1 +--conn-redeliveries-max 1 +--conn-server-stack-trace-ena false +--conn-sync-send true +--conn-tcp-buf-size-recv 1 +--conn-tcp-buf-size-send 1 +--conn-tcp-conn-timeout 1000 +--conn-tcp-keep-alive true +--conn-tcp-no-delay false +--conn-tcp-sock-linger 1000 +--conn-tcp-sock-timeout 1000 +--conn-tcp-traffic-class 1 +--conn-tight-encoding-ena false +--conn-topic-prefix aTopicPrefix +--conn-valid-prop-names false """.split(" ", "\n").toTypedArray() override fun main(args: Array) = Main.main(args) diff --git a/cli-qpid-jms/src/test/kotlin/MainTest.kt b/cli-qpid-jms/src/test/kotlin/MainTest.kt index bf741930..7a95bd59 100644 --- a/cli-qpid-jms/src/test/kotlin/MainTest.kt +++ b/cli-qpid-jms/src/test/kotlin/MainTest.kt @@ -80,6 +80,46 @@ class AacMainTest : AbstractMainTest() { --property-type String """.split(" ", "\n").toTypedArray() + + override val connectorAdditionalOptions = """ +--conn-async-send true +--conn-auth-mechanisms anonymous +--conn-auth-sasl false +--conn-clientid aClientId +--conn-clientid-prefix aClientIdPrefix +--conn-close-timeout 1000 +--conn-conn-timeout 1000 +--conn-connid-prefix aConnIdPrefix +--conn-heartbeat 1000 +--conn-local-msg-priority true +--conn-max-frame-size 4096 +--conn-prefetch 1 +--conn-prefetch-browser 1 +--conn-prefetch-queue 1 +--conn-prefetch-topic 1 +--conn-prefetch-topic-dur 1 +--conn-queue-prefix aQueuePrefix +--conn-reconnect true +--conn-reconnect-backoff false +--conn-reconnect-backoff-multiplier 1 +--conn-reconnect-initial-delay 1 +--conn-reconnect-interval 1000 +--conn-reconnect-limit 1000 +--conn-reconnect-start-limit 1000 +--conn-reconnect-timeout 1000 +--conn-reconnect-warn-attempts 1 +--conn-redeliveries-max 1 +--conn-tcp-buf-size-recv 1 +--conn-tcp-buf-size-send 1 +--conn-tcp-conn-timeout 1000 +--conn-tcp-keep-alive true +--conn-tcp-no-delay false +--conn-tcp-sock-timeout 1000 +--conn-tcp-traffic-class 1 +--conn-topic-prefix aTopicPrefix +--conn-valid-prop-names false +""".split(" ", "\n").toTypedArray() + override fun main(args: Array) = Main.main(args) } diff --git a/tests/connector.pict b/tests/connector.pict new file mode 100644 index 00000000..1458da6d --- /dev/null +++ b/tests/connector.pict @@ -0,0 +1,7 @@ +--log-lib: trace, debug, info, warn, error, all, fatal, off, aLogLibValue +--log-stats: trace, debug, info, warn, error, all, fatal, off, aLogLibValue +--obj-ctrl: C, E, S, R, Q +// --q-count: 1, (100) // not implemented in aoc,acc +--ssn-ack-mode: auto, client, dups_ok +--sync-mode: none, session, action, persistent, transient +--close-sleep: 1, (100) diff --git a/tests/generate_csv_from_pict.py b/tests/generate_csv_from_pict.py index 245bfbd8..128dd560 100644 --- a/tests/generate_csv_from_pict.py +++ b/tests/generate_csv_from_pict.py @@ -1,6 +1,5 @@ from __future__ import print_function - import pandas # ./pict model.pict /o:1 @@ -18,7 +17,7 @@ def add_option(options, option): if not option[0].startswith('--'): return (option[1],) + options # default case - return option+options + return option + options def convert(source_filename, destination_filename): @@ -31,6 +30,6 @@ def convert(source_filename, destination_filename): if __name__ == '__main__': - files = ['sender', 'receiver'] + files = ['sender', 'receiver', 'connector'] for file in files: convert(file + '.out', file + '.csv') diff --git a/tests/src/test/kotlin/AbstractMainTest.kt b/tests/src/test/kotlin/AbstractMainTest.kt index 7e287b27..e6e6cca4 100644 --- a/tests/src/test/kotlin/AbstractMainTest.kt +++ b/tests/src/test/kotlin/AbstractMainTest.kt @@ -77,6 +77,7 @@ abstract class AbstractMainTest { * Used in a test to increase code coverage and catch some unforeseen option interactions. */ abstract val senderAdditionalOptions: Array + abstract val connectorAdditionalOptions: Array val prefix: String = "lalaLand_" lateinit var randomSuffix: String @@ -227,6 +228,19 @@ abstract class AbstractMainTest { } } + @ParameterizedTest + @CsvFileSource(resources = arrayOf("/connector.csv")) + fun connectConnectorWithAllSenderCLISwitches(senderDynamicOptions: String) { + println(senderDynamicOptions) + val connectorPrameters = + "connector --broker $brokerUrl --address $address".split(" ").toTypedArray() + + assertNoSystemExit { + print("Connecting: ") + main(connectorPrameters + senderDynamicOptions.split(" ").toTypedArray() + connectorAdditionalOptions) + } + } + @Test fun sendAndReceiveListMessage() { val senderParameters = diff --git a/tests/src/test/resources/connector.csv b/tests/src/test/resources/connector.csv new file mode 100644 index 00000000..678d71ae --- /dev/null +++ b/tests/src/test/resources/connector.csv @@ -0,0 +1,9 @@ +--close-sleep 1.0 --sync-mode session --ssn-ack-mode auto --obj-ctrl S --log-stats all --log-lib trace +--sync-mode none --ssn-ack-mode dups_ok 1.0 --obj-ctrl C --log-stats warn --log-lib all +--sync-mode transient --ssn-ack-mode client --obj-ctrl E --log-stats debug --log-lib off +--sync-mode action --ssn-ack-mode client --obj-ctrl Q --log-stats fatal --log-lib error +--sync-mode persistent --ssn-ack-mode auto --obj-ctrl R --log-stats error --log-lib info +--sync-mode action --ssn-ack-mode auto --obj-ctrl R --log-stats off --log-lib fatal +--sync-mode session --ssn-ack-mode client --obj-ctrl C --log-stats trace --log-lib warn +--sync-mode action --ssn-ack-mode auto --obj-ctrl C --log-stats info --log-lib aLogLibValue +--sync-mode session --ssn-ack-mode auto 1.0 --obj-ctrl C --log-stats aLogLibValue --log-lib debug From 650b0441414c33388c266c895546aa6a8c28c5bb Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Tue, 17 Oct 2017 13:25:46 +0200 Subject: [PATCH 008/740] Add test for QPIDJMS-286 Shorten the thread name given to the AmqpProvider executor thread --- .../src/test/kotlin/QPIDJMS286Test.kt | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 cli-qpid-jms/src/test/kotlin/QPIDJMS286Test.kt diff --git a/cli-qpid-jms/src/test/kotlin/QPIDJMS286Test.kt b/cli-qpid-jms/src/test/kotlin/QPIDJMS286Test.kt new file mode 100644 index 00000000..0fae8b31 --- /dev/null +++ b/cli-qpid-jms/src/test/kotlin/QPIDJMS286Test.kt @@ -0,0 +1,40 @@ +import com.google.common.truth.Truth +import org.junit.jupiter.api.Test + +/* + * Copyright (c) 2017 Red Hat, Inc. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class QPIDJMS286Test { + @Test + fun `uri options are not visible in thread names`() { + val f = org.apache.qpid.jms.JmsConnectionFactory( + "amqp://127.0.0.1:5672?jms.username=anUserName&jms.password=aPassword&amqp.vhost=aVHostNotPassword") + val c = f.createConnection() + val s = c.createSession() + + val threadSet = Thread.getAllStackTraces().keys + threadSet.forEach { + println(it.name) + Truth.assertThat(it.name).doesNotContain("Password") + } + + s.close() + c.close() + } +} From 40ec4d3d71cd610d40a08b1e8012c399efc2a88e Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Tue, 17 Oct 2017 11:22:48 +0200 Subject: [PATCH 009/740] Add self test sendAndReceiveMessageToTopic --- tests/src/test/kotlin/AbstractMainTest.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/src/test/kotlin/AbstractMainTest.kt b/tests/src/test/kotlin/AbstractMainTest.kt index e6e6cca4..4638a4a2 100644 --- a/tests/src/test/kotlin/AbstractMainTest.kt +++ b/tests/src/test/kotlin/AbstractMainTest.kt @@ -253,4 +253,22 @@ abstract class AbstractMainTest { print("Receiving: ") main(receiverParameters) } + + @Test + fun sendAndReceiveMessageToTopic() { + val senderParameters = + "sender --log-msgs dict --broker $brokerUrl --address topic://$address --count 1".split(" ").toTypedArray() + val receiverParameters = + "receiver --log-msgs dict --broker $brokerUrl --address topic://$address --count 1".split(" ").toTypedArray() + + val t = Thread { + print("Receiving: ") + main(receiverParameters) + } + t.start() + Thread.sleep(1000) + print("Sending: ") + main(senderParameters) + t.join() + } } From a58f00455941041703cd631d091d088fe91fe15e Mon Sep 17 00:00:00 2001 From: Michal T Date: Wed, 25 Oct 2017 13:08:53 +0200 Subject: [PATCH 010/740] Update entrypoint.sh --- scripts/entrypoint.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 7183a4cb..ccec8594 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -19,10 +19,8 @@ if [ ! "$(ls -A /var/lib/amq7/etc)" ]; then --role $ENV_AMQ7_ROLE \ --allow-anonymous \ --cluster-user $ENV_AMQ7_CLUSTER_USER \ - --cluster-password $ENV_AMQ7_CLUSTER_PASSWORD - - # Get managment accesible from the outside - sed -ie 's/localhost:8161/0.0.0.0:8161/g' amq7/etc/bootstrap.xml + --cluster-password $ENV_AMQ7_CLUSTER_PASSWORD \ + --http-host 0.0.0.0 chown -R amq7:amq7 /var/lib/amq7 From 9a27e7debfe86b9383db169081a54b99e613152e Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 12:35:03 +0200 Subject: [PATCH 011/740] Add .gitignore for Maven --- .gitignore | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index 9938544a..5c253208 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,17 @@ crashlytics.properties crashlytics-build.properties fabric.properties +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) +!/.mvn/wrapper/maven-wrapper.jar + From b6fc871de8de1e8b4b4fe178be6a09ee8edb30df Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Mon, 9 Oct 2017 20:46:47 +0200 Subject: [PATCH 012/740] Reformat Java sources to four spaces indentation --- .../redhat/mqe/aoc/AocConnectionManager.java | 2 +- .../mqe/aoc/AocConnectionManagerFactory.java | 6 +- .../mqe/acc/AccClientOptionManager.java | 1 + .../redhat/mqe/acc/AccConnectionManager.java | 4 +- .../mqe/acc/AccConnectionManagerFactory.java | 6 +- .../java/com/redhat/mqe/jms/BrokerAgent.java | 16 +- .../redhat/mqe/jms/BrokerAgentOptions.java | 24 +- .../redhat/mqe/jms/ClientOptionManager.java | 631 +++++----- .../com/redhat/mqe/jms/ClientOptions.java | 654 +++++----- .../com/redhat/mqe/jms/ConnectionManager.java | 332 ++--- .../com/redhat/mqe/jms/ConnectorClient.java | 218 ++-- .../com/redhat/mqe/jms/ConnectorOptions.java | 108 +- .../java/com/redhat/mqe/jms/CoreClient.java | 1025 ++++++++-------- .../com/redhat/mqe/jms/MessageBrowser.java | 90 +- .../redhat/mqe/jms/MessageListenerImpl.java | 16 +- .../com/redhat/mqe/jms/ReceiverClient.java | 440 +++---- .../com/redhat/mqe/jms/ReceiverOptions.java | 164 +-- .../java/com/redhat/mqe/jms/SenderClient.java | 1070 ++++++++-------- .../com/redhat/mqe/jms/SenderOptions.java | 190 +-- .../com/redhat/mqe/jms/aac1_connector.java | 10 +- .../com/redhat/mqe/jms/aac1_receiver.java | 22 +- .../java/com/redhat/mqe/jms/aac1_sender.java | 10 +- .../redhat/mqe/lib/AMQPMessageFormatter.java | 174 +-- .../redhat/mqe/lib/ClientOptionManager.java | 711 +++++------ .../com/redhat/mqe/lib/ClientOptions.java | 670 +++++----- .../com/redhat/mqe/lib/ConnectionManager.java | 16 +- .../com/redhat/mqe/lib/ConnectorClient.java | 167 +-- .../com/redhat/mqe/lib/ConnectorOptions.java | 106 +- .../main/java/com/redhat/mqe/lib/Content.java | 152 +-- .../java/com/redhat/mqe/lib/CoreClient.java | 766 ++++++------ .../redhat/mqe/lib/CoreMessageFormatter.java | 204 +-- .../redhat/mqe/lib/JmsMessagingException.java | 23 +- .../com/redhat/mqe/lib/MessageBrowser.java | 80 +- .../com/redhat/mqe/lib/MessageFormatter.java | 635 +++++----- .../redhat/mqe/lib/MessageListenerImpl.java | 16 +- .../mqe/lib/OpenwireMessageFormatter.java | 208 ++-- .../main/java/com/redhat/mqe/lib/Option.java | 373 +++--- .../com/redhat/mqe/lib/ReceiverClient.java | 450 +++---- .../com/redhat/mqe/lib/ReceiverOptions.java | 164 +-- .../java/com/redhat/mqe/lib/SenderClient.java | 1092 +++++++++-------- .../com/redhat/mqe/lib/SenderOptions.java | 190 +-- .../main/java/com/redhat/mqe/lib/Utils.java | 605 ++++----- 42 files changed, 5934 insertions(+), 5907 deletions(-) diff --git a/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManager.java b/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManager.java index 3e88d811..65d3ef7d 100644 --- a/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManager.java +++ b/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManager.java @@ -56,7 +56,7 @@ class AocConnectionManager extends ConnectionManager { LOG.debug("Connection=" + connectionFactory); LOG.trace("Destination=" + destination); if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue() - || (username == null && password == null)) { + || (username == null && password == null)) { // || CoreClient.isAMQClient()) { this will work for Qpid JMS AMQP Client as well, but we will be nicer connection = factory.createConnection(); } else { diff --git a/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManagerFactory.java b/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManagerFactory.java index cdff1325..6733f724 100644 --- a/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManagerFactory.java +++ b/cli-activemq/src/main/java/com/redhat/mqe/aoc/AocConnectionManagerFactory.java @@ -22,8 +22,10 @@ import com.redhat.mqe.lib.ClientOptions; import com.redhat.mqe.lib.ConnectionManagerFactory; -public class AocConnectionManagerFactory extends ConnectionManagerFactory{ - AocConnectionManagerFactory() {} +public class AocConnectionManagerFactory extends ConnectionManagerFactory { + AocConnectionManagerFactory() { + } + public AocConnectionManager make(ClientOptions clientOptions, String brokerUri) { return new AocConnectionManager(clientOptions, brokerUri); } diff --git a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java index 0997b669..03ebea23 100644 --- a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java +++ b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccClientOptionManager.java @@ -27,6 +27,7 @@ class AccClientOptionManager extends ClientOptionManager { private Map CTL_SSL_OPTIONS = new HashMap<>(); + { // Core // org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java diff --git a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManager.java b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManager.java index dc664d6b..f4bfb991 100644 --- a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManager.java +++ b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManager.java @@ -66,7 +66,7 @@ public class AccConnectionManager extends ConnectionManager { LOG.debug("Connection=" + connectionFactory); LOG.trace("Destination=" + destination); if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue() - || (username == null && password == null)) { + || (username == null && password == null)) { // || CoreClient.isAMQClient()) { this will work for Qpid JMS AMQP Client as well, but we will be nicer connection = factory.createConnection(); } else { @@ -79,7 +79,7 @@ public class AccConnectionManager extends ConnectionManager { @Override public void onException(JMSException exception) { if (clientOptions.getOption(ClientOptions.CON_RECONNECT).getValue().matches("[tT]rue") && - (exception.getCause() instanceof ActiveMQDisconnectedException || + (exception.getCause() instanceof ActiveMQDisconnectedException || exception.getCause() instanceof ActiveMQNotConnectedException)) { return; } diff --git a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManagerFactory.java b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManagerFactory.java index da95f6ce..44ebd5bb 100644 --- a/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManagerFactory.java +++ b/cli-artemis-jms/src/main/java/com/redhat/mqe/acc/AccConnectionManagerFactory.java @@ -22,8 +22,10 @@ import com.redhat.mqe.lib.ClientOptions; import com.redhat.mqe.lib.ConnectionManagerFactory; -public class AccConnectionManagerFactory extends ConnectionManagerFactory{ - AccConnectionManagerFactory() {} +public class AccConnectionManagerFactory extends ConnectionManagerFactory { + AccConnectionManagerFactory() { + } + public AccConnectionManager make(ClientOptions clientOptions, String brokerUri) { return new AccConnectionManager(clientOptions, brokerUri); } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgent.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgent.java index 2395742b..c84b780d 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgent.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgent.java @@ -24,13 +24,13 @@ public class BrokerAgent extends CoreClient { - @Override - ClientOptions getClientOptions() { - return null; - } + @Override + ClientOptions getClientOptions() { + return null; + } - @Override - void startClient() { - // TODO if needed? - } + @Override + void startClient() { + // TODO if needed? + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgentOptions.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgentOptions.java index f6573554..11bbb5c6 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgentOptions.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/BrokerAgentOptions.java @@ -27,18 +27,18 @@ */ public class BrokerAgentOptions extends ClientOptions { - @Override - public com.redhat.mqe.lib.Option getOption(String name) { - return null; - } + @Override + public com.redhat.mqe.lib.Option getOption(String name) { + return null; + } - @Override - public List getClientDefaultOptions() { - return null; - } + @Override + public List getClientDefaultOptions() { + return null; + } - @Override - public List getClientOptions() { - return null; - } + @Override + public List getClientOptions() { + return null; + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptionManager.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptionManager.java index da73ebcf..a298c387 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptionManager.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptionManager.java @@ -37,361 +37,362 @@ * client options list, then accordingly set for client. */ public class ClientOptionManager { - private static final Logger LOG = LoggerFactory.getLogger(ClientOptionManager.class); - private ClientOptions clientOptions; - private static List updatedOptions = new ArrayList<>(); - private static final String QUEUE_PREFIX = "queue://"; - private static final String TOPIC_PREFIX = "topic://"; + private static final Logger LOG = LoggerFactory.getLogger(ClientOptionManager.class); + private ClientOptions clientOptions; + private static List updatedOptions = new ArrayList<>(); + private static final String QUEUE_PREFIX = "queue://"; + private static final String TOPIC_PREFIX = "topic://"; - private static final String protocol = "(?\\w+(?:\\+?\\w+)*://)?"; - private static final String credentials = "(?:(?\\w*)?:?(?\\w*)?@)?"; - private static final String hostname = "(?\\[[a-fA-F0-9:]+\\]|[a-zA-Z0-9-_.]+):(?[0-9]+)"; - private static final String query = "(?:\\?(?.*)?)?"; + private static final String protocol = "(?\\w+(?:\\+?\\w+)*://)?"; + private static final String credentials = "(?:(?\\w*)?:?(?\\w*)?@)?"; + private static final String hostname = "(?\\[[a-fA-F0-9:]+\\]|[a-zA-Z0-9-_.]+):(?[0-9]+)"; + private static final String query = "(?:\\?(?.*)?)?"; - public ClientOptionManager(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - } + public ClientOptionManager(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + } - /** - * Apply parsed command line values to the supplied client options. - * - * @param clientOptions to be updated - * @param args user command line arguments to be parsed - */ - static void applyClientArguments(ClientOptions clientOptions, String[] args) { - OptionParser parser = createParser(clientOptions.getClientOptions()); - parseInputOptions(clientOptions, parser, args); - } + /** + * Apply parsed command line values to the supplied client options. + * + * @param clientOptions to be updated + * @param args user command line arguments to be parsed + */ + static void applyClientArguments(ClientOptions clientOptions, String[] args) { + OptionParser parser = createParser(clientOptions.getClientOptions()); + parseInputOptions(clientOptions, parser, args); + } - public ClientOptions getClientOptions() { - return clientOptions; - } + public ClientOptions getClientOptions() { + return clientOptions; + } - /** - * Create jOpt parser from supplied client options. - * - * @param options allowed by client - * @return jOpt parser - */ - public static OptionParser createParser(List options) { - OptionParser parser = new OptionParser(); - for (com.redhat.mqe.lib.Option opt : options) { - if (opt.isCliArgument()) { - if (opt.getLongOptionName().equals(ClientOptions.HELP)) { - parser.acceptsAll(Arrays.asList(opt.getShortOptionName(), - opt.getLongOptionName()), opt.getDescription()).isForHelp(); - continue; - } + /** + * Create jOpt parser from supplied client options. + * + * @param options allowed by client + * @return jOpt parser + */ + public static OptionParser createParser(List options) { + OptionParser parser = new OptionParser(); + for (com.redhat.mqe.lib.Option opt : options) { + if (opt.isCliArgument()) { + if (opt.getLongOptionName().equals(ClientOptions.HELP)) { + parser.acceptsAll(Arrays.asList(opt.getShortOptionName(), + opt.getLongOptionName()), opt.getDescription()).isForHelp(); + continue; + } - // username and password options can have no argument - if (opt.getLongOptionName().equals(ClientOptions.USERNAME) - || opt.getLongOptionName().equals(ClientOptions.PASSWORD)) { - parser.accepts(opt.getLongOptionName()).withOptionalArg().ofType(String.class).describedAs(opt.getDescription()); - continue; - } + // username and password options can have no argument + if (opt.getLongOptionName().equals(ClientOptions.USERNAME) + || opt.getLongOptionName().equals(ClientOptions.PASSWORD)) { + parser.accepts(opt.getLongOptionName()).withOptionalArg().ofType(String.class).describedAs(opt.getDescription()); + continue; + } - OptionSpecBuilder optionSpecBuilder; - if (!opt.getShortOptionName().equals("") && !opt.getLongOptionName().equals("")) { - optionSpecBuilder = parser.acceptsAll(Arrays.asList(opt.getShortOptionName(), - opt.getLongOptionName()), opt.getDescription()); - } else if (opt.getLongOptionName().equals("")) { - optionSpecBuilder = parser.accepts(opt.getShortOptionName(), opt.getDescription()); - } else { - optionSpecBuilder = parser.accepts(opt.getLongOptionName(), opt.getDescription()); - } + OptionSpecBuilder optionSpecBuilder; + if (!opt.getShortOptionName().equals("") && !opt.getLongOptionName().equals("")) { + optionSpecBuilder = parser.acceptsAll(Arrays.asList(opt.getShortOptionName(), + opt.getLongOptionName()), opt.getDescription()); + } else if (opt.getLongOptionName().equals("")) { + optionSpecBuilder = parser.accepts(opt.getShortOptionName(), opt.getDescription()); + } else { + optionSpecBuilder = parser.accepts(opt.getLongOptionName(), opt.getDescription()); + } - if (opt.hasArgument()) { - ArgumentAcceptingOptionSpec optionSpec = optionSpecBuilder.withRequiredArg().describedAs(opt.getArgumentExample()); - // TODO possibly all options with arguments should have default values(?) - if (!opt.getDefaultValue().equals("")) { - optionSpec.defaultsTo(opt.getDefaultValue()); - } + if (opt.hasArgument()) { + ArgumentAcceptingOptionSpec optionSpec = optionSpecBuilder.withRequiredArg().describedAs(opt.getArgumentExample()); + // TODO possibly all options with arguments should have default values(?) + if (!opt.getDefaultValue().equals("")) { + optionSpec.defaultsTo(opt.getDefaultValue()); + } + } + } } - } + return parser; } - return parser; - } - /** - * Parse the options. Print help if "help" was supplied. - * - * @param clientOptions supplied client options - * @param parser jOpt parser to be used for parsing command line arguemnts - * @param argv user command line input - */ - public static void parseInputOptions(ClientOptions clientOptions, OptionParser parser, String[] argv) { - try { - OptionSet options = parser.parse(argv); + /** + * Parse the options. Print help if "help" was supplied. + * + * @param clientOptions supplied client options + * @param parser jOpt parser to be used for parsing command line arguemnts + * @param argv user command line input + */ + public static void parseInputOptions(ClientOptions clientOptions, OptionParser parser, String[] argv) { + try { + OptionSet options = parser.parse(argv); - if (options.has(ClientOptions.HELP)) { - printHelp(parser); - System.exit(0); - } else { - // Iterate over options & set client option/s accordingly - for (Map.Entry, List> entry : options.asMap().entrySet()) { - OptionSpec spec = entry.getKey(); - if (options.has(spec)) { - LOG.trace(spec + " : " + entry.getValue() + " :: " + options.has(spec)); - // Set parsed option for the client option - try { - setClientOptions(clientOptions.getOption(getOptionName(spec.options())), options, clientOptions); - } catch (JmsMessagingException me) { - LOG.error(me.toString(), me.getMessage()); - me.printStackTrace(); - System.exit(2); - } - } - } - clientOptions.setUpdatedOptions(updatedOptions); - createConnectionOptions(clientOptions); - if (clientOptions.getUpdatedOptionsMap().keySet().contains(ClientOptions.BROKER) - || !clientOptions.getUpdatedOptionsMap().keySet().contains(ClientOptions.BROKER_URI) ) { - checkAndSetOption(ClientOptions.BROKER, - clientOptions.getOption(ClientOptions.BROKER).getValue() + CoreClient.getConnectionOptionsAsUrl(), - clientOptions); - } - // Check if use transactions (set it all accordingly, if yes) - if (options.has(ClientOptions.TX_SIZE) || options.has(ClientOptions.TX_ACTION) || options.has(ClientOptions.TX_ENDLOOP_ACTION)) { - checkAndSetOption(clientOptions.getOption(ClientOptions.TRANSACTED).getName(), "true", clientOptions); + if (options.has(ClientOptions.HELP)) { + printHelp(parser); + System.exit(0); + } else { + // Iterate over options & set client option/s accordingly + for (Map.Entry, List> entry : options.asMap().entrySet()) { + OptionSpec spec = entry.getKey(); + if (options.has(spec)) { + LOG.trace(spec + " : " + entry.getValue() + " :: " + options.has(spec)); + // Set parsed option for the client option + try { + setClientOptions(clientOptions.getOption(getOptionName(spec.options())), options, clientOptions); + } catch (JmsMessagingException me) { + LOG.error(me.toString(), me.getMessage()); + me.printStackTrace(); + System.exit(2); + } + } + } + clientOptions.setUpdatedOptions(updatedOptions); + createConnectionOptions(clientOptions); + if (clientOptions.getUpdatedOptionsMap().keySet().contains(ClientOptions.BROKER) + || !clientOptions.getUpdatedOptionsMap().keySet().contains(ClientOptions.BROKER_URI)) { + checkAndSetOption(ClientOptions.BROKER, + clientOptions.getOption(ClientOptions.BROKER).getValue() + CoreClient.getConnectionOptionsAsUrl(), + clientOptions); + } + // Check if use transactions (set it all accordingly, if yes) + if (options.has(ClientOptions.TX_SIZE) || options.has(ClientOptions.TX_ACTION) || options.has(ClientOptions.TX_ENDLOOP_ACTION)) { + checkAndSetOption(clientOptions.getOption(ClientOptions.TRANSACTED).getName(), "true", clientOptions); + } + } + } catch (OptionException x) { + System.err.println("Unknown parameter has been detected: " + x.getMessage()); + printHelp(parser); + System.exit(2); } - } - } catch (OptionException x) { - System.err.println("Unknown parameter has been detected: " + x.getMessage()); - printHelp(parser); - System.exit(2); } - } - private static void createConnectionOptions(ClientOptions clientOptions) { + private static void createConnectionOptions(ClientOptions clientOptions) { // for (Option clientOption : clientOptions.getClientOptions()) { - for (com.redhat.mqe.lib.Option clientOption : clientOptions.getUpdatedOptions()) { - // OptionName starts with "conn-" - if (clientOption.getName().startsWith(ClientOptions.CON_HEARTBEAT.substring(0, 4))) { - CoreClient.addConnectionOptions(clientOption); - } + for (com.redhat.mqe.lib.Option clientOption : clientOptions.getUpdatedOptions()) { + // OptionName starts with "conn-" + if (clientOption.getName().startsWith(ClientOptions.CON_HEARTBEAT.substring(0, 4))) { + CoreClient.addConnectionOptions(clientOption); + } + } } - } - /** - * Workaround for unmodifiable list, to always get the longOption (= option name). - * - * @param options list of current options - * @return longOption Option name - */ - private static String getOptionName(List options) { - List tmp = new ArrayList<>(options); - if (options.size() > 1) { - Collections.sort(tmp, new StringLengthComparator()); + /** + * Workaround for unmodifiable list, to always get the longOption (= option name). + * + * @param options list of current options + * @return longOption Option name + */ + private static String getOptionName(List options) { + List tmp = new ArrayList<>(options); + if (options.size() > 1) { + Collections.sort(tmp, new StringLengthComparator()); + } + return tmp.get(0); } - return tmp.get(0); - } - /** - * Set client option based on command line arguments. - * Option.parsedValue is set accordingly. - * - * @param clientOption Option of the client - * @param options parsed option from command line - * @throws JmsMessagingException - */ - private static void setClientOptions(com.redhat.mqe.lib.Option clientOption, OptionSet options, ClientOptions clientOptions) throws JmsMessagingException { - // Check for multiple argument input values - if (options.valuesOf(clientOption.getName()).size() == 1 - && !ClientOptions.argsAcceptingMultipleValues.contains(clientOption.getName())) { - LOG.trace("Single value: " + options.valueOf(clientOption.getName())); - String optionName = clientOption.getName(); - if (optionName.equals(ClientOptions.BROKER)) { - setBrokerOptions(clientOptions, (String) options.valueOf(optionName)); - // Set parsed value from options (set without "broker options" only when --broker arg.) - clientOption.setParsedValue(CoreClient.formBrokerUrl(clientOptions)); - // formatAddress and set type & name for ConnectionManager - } else if (optionName.equals(ClientOptions.ADDRESS)) { - String address = (String) options.valueOf(ClientOptions.ADDRESS); - if (address.startsWith(TOPIC_PREFIX)) { - checkAndSetOption(ClientOptions.DESTINATION_TYPE, ConnectionManager.TOPIC_OBJECT, clientOptions); - } - if (address.startsWith(TOPIC_PREFIX) || address.startsWith(QUEUE_PREFIX)) { - address = address.substring(TOPIC_PREFIX.length()); // len(TOPIC_PREFIX==QUEUE_PREFIX) + /** + * Set client option based on command line arguments. + * Option.parsedValue is set accordingly. + * + * @param clientOption Option of the client + * @param options parsed option from command line + * @throws JmsMessagingException + */ + private static void setClientOptions(com.redhat.mqe.lib.Option clientOption, OptionSet options, ClientOptions clientOptions) throws JmsMessagingException { + // Check for multiple argument input values + if (options.valuesOf(clientOption.getName()).size() == 1 + && !ClientOptions.argsAcceptingMultipleValues.contains(clientOption.getName())) { + LOG.trace("Single value: " + options.valueOf(clientOption.getName())); + String optionName = clientOption.getName(); + if (optionName.equals(ClientOptions.BROKER)) { + setBrokerOptions(clientOptions, (String) options.valueOf(optionName)); + // Set parsed value from options (set without "broker options" only when --broker arg.) + clientOption.setParsedValue(CoreClient.formBrokerUrl(clientOptions)); + // formatAddress and set type & name for ConnectionManager + } else if (optionName.equals(ClientOptions.ADDRESS)) { + String address = (String) options.valueOf(ClientOptions.ADDRESS); + if (address.startsWith(TOPIC_PREFIX)) { + checkAndSetOption(ClientOptions.DESTINATION_TYPE, ConnectionManager.TOPIC_OBJECT, clientOptions); + } + if (address.startsWith(TOPIC_PREFIX) || address.startsWith(QUEUE_PREFIX)) { + address = address.substring(TOPIC_PREFIX.length()); // len(TOPIC_PREFIX==QUEUE_PREFIX) + } + checkAndSetOption(ClientOptions.ADDRESS, address, clientOptions); + LOG.trace("Address=" + clientOption.getValue()); + } else { + clientOption.setParsedValue(options.valueOf(clientOption.getName())); + } + } else if (options.valuesOf(clientOption.getName()).size() == 0) { + if (clientOption.getName().equals(ClientOptions.USERNAME) + || clientOption.getName().equals(ClientOptions.PASSWORD)) { + clientOption.setParsedValue(clientOption.getDefaultValue()); + } else { + // no argument option (switch) + clientOption.setParsedValue("true"); + LOG.trace("Enabled no argument option: " + clientOption.getName()); + } + } else { + // has multiple values, set only allowed types with multiple values + LOG.trace("Multiple values: " + options.valuesOf(clientOption.getName())); + if (ClientOptions.argsAcceptingMultipleValues.contains(clientOption.getName())) { + clientOption.setParsedValue(options.valuesOf(clientOption.getName())); + } else { + // if (option not in allowedMultiArgsList): + throw new JmsMessagingException("Option " + clientOption.getName() + + " has wrong argument(s): " + options.valueOf(clientOption.getName())); + } } - checkAndSetOption(ClientOptions.ADDRESS, address, clientOptions); - LOG.trace("Address=" + clientOption.getValue()); - } else { - clientOption.setParsedValue(options.valueOf(clientOption.getName())); - } - } else if (options.valuesOf(clientOption.getName()).size() == 0) { - if (clientOption.getName().equals(ClientOptions.USERNAME) - || clientOption.getName().equals(ClientOptions.PASSWORD)) { - clientOption.setParsedValue(clientOption.getDefaultValue()); - } else { - // no argument option (switch) - clientOption.setParsedValue("true"); - LOG.trace("Enabled no argument option: " + clientOption.getName()); - } - } else { - // has multiple values, set only allowed types with multiple values - LOG.trace("Multiple values: " + options.valuesOf(clientOption.getName())); - if (ClientOptions.argsAcceptingMultipleValues.contains(clientOption.getName())) { - clientOption.setParsedValue(options.valuesOf(clientOption.getName())); - } else { - // if (option not in allowedMultiArgsList): - throw new JmsMessagingException("Option " + clientOption.getName() - + " has wrong argument(s): " + options.valueOf(clientOption.getName())); - } + updatedOptions.add(clientOption); } - updatedOptions.add(clientOption); - } - /** - * Gather data for protocol,username,password, primary host,port and options - * provided from 'broker' or 'broker-url' argument. - * - * @param clientOptions - * @param brokerUrl - */ - private static void setBrokerOptions(ClientOptions clientOptions, String brokerUrl) { - // TODO new discovery failover has been added - // TODO failover.nested options for clients has been changed, broker in list can have custom options - Map patternOptionMapping = new HashMap<>(); - patternOptionMapping.put("protocol", ClientOptions.PROTOCOL); - patternOptionMapping.put("username", ClientOptions.USERNAME); - patternOptionMapping.put("password", ClientOptions.PASSWORD); - patternOptionMapping.put("hostname", ClientOptions.BROKER_HOST); - patternOptionMapping.put("port", ClientOptions.BROKER_PORT); - patternOptionMapping.put("query", ClientOptions.BROKER_OPTIONS); + /** + * Gather data for protocol,username,password, primary host,port and options + * provided from 'broker' or 'broker-url' argument. + * + * @param clientOptions + * @param brokerUrl + */ + private static void setBrokerOptions(ClientOptions clientOptions, String brokerUrl) { + // TODO new discovery failover has been added + // TODO failover.nested options for clients has been changed, broker in list can have custom options + Map patternOptionMapping = new HashMap<>(); + patternOptionMapping.put("protocol", ClientOptions.PROTOCOL); + patternOptionMapping.put("username", ClientOptions.USERNAME); + patternOptionMapping.put("password", ClientOptions.PASSWORD); + patternOptionMapping.put("hostname", ClientOptions.BROKER_HOST); + patternOptionMapping.put("port", ClientOptions.BROKER_PORT); + patternOptionMapping.put("query", ClientOptions.BROKER_OPTIONS); - String uriProtocol = null; - if (Boolean.parseBoolean(clientOptions.getOption(ClientOptions.CON_RECONNECT).getValue())) { - // use failover mechanism by default, discovery otherwise - // TODO detect & set discovery option in future - if (brokerUrl.startsWith(ClientOptions.DISCOVERY_PROTO)) { - uriProtocol = ClientOptions.DISCOVERY_PROTO; - } else { - uriProtocol = ClientOptions.FAILOVER_PROTO; - } - } - if (uriProtocol != null) { - checkAndSetOption(ClientOptions.PROTOCOL, uriProtocol, clientOptions); - // Set the whole url as failoverUrl. Do not parse it. connection options should come as input "conn-*" - brokerUrl = appendMissingProtocol(brokerUrl); - checkAndSetOption(ClientOptions.FAILOVER_URL, brokerUrl, clientOptions); - } else { - // Search for the first protocol, hostname and port in provided url. Also get username and password if they are provided - Pattern pattern; - if (CoreClient.isAMQClient()) { - pattern = Pattern.compile(protocol + hostname + query); - } else { - pattern = Pattern.compile(protocol + credentials + hostname + query); - } - Matcher matcher = pattern.matcher(brokerUrl); - if (matcher.find()) { - for (String groupName : patternOptionMapping.keySet()) { - try { - if (matcher.group(groupName) != null) - checkAndSetOption(patternOptionMapping.get(groupName), matcher.group(groupName), clientOptions); - } catch (IllegalArgumentException e) { - LOG.trace("Group {} not found", groupName); - } + String uriProtocol = null; + if (Boolean.parseBoolean(clientOptions.getOption(ClientOptions.CON_RECONNECT).getValue())) { + // use failover mechanism by default, discovery otherwise + // TODO detect & set discovery option in future + if (brokerUrl.startsWith(ClientOptions.DISCOVERY_PROTO)) { + uriProtocol = ClientOptions.DISCOVERY_PROTO; + } else { + uriProtocol = ClientOptions.FAILOVER_PROTO; + } + } + if (uriProtocol != null) { + checkAndSetOption(ClientOptions.PROTOCOL, uriProtocol, clientOptions); + // Set the whole url as failoverUrl. Do not parse it. connection options should come as input "conn-*" + brokerUrl = appendMissingProtocol(brokerUrl); + checkAndSetOption(ClientOptions.FAILOVER_URL, brokerUrl, clientOptions); + } else { + // Search for the first protocol, hostname and port in provided url. Also get username and password if they are provided + Pattern pattern; + if (CoreClient.isAMQClient()) { + pattern = Pattern.compile(protocol + hostname + query); + } else { + pattern = Pattern.compile(protocol + credentials + hostname + query); + } + Matcher matcher = pattern.matcher(brokerUrl); + if (matcher.find()) { + for (String groupName : patternOptionMapping.keySet()) { + try { + if (matcher.group(groupName) != null) + checkAndSetOption(patternOptionMapping.get(groupName), matcher.group(groupName), clientOptions); + } catch (IllegalArgumentException e) { + LOG.trace("Group {} not found", groupName); + } + } + } else { + LOG.error("Wrongly parsed BrokerURI:\"" + brokerUrl + "\""); + System.exit(2); + } } - } else { - LOG.error("Wrongly parsed BrokerURI:\"" + brokerUrl +"\""); - System.exit(2); - } } - } - /** - * Append an AMQP protocol to broker url for all possible connecting options (simple, failover, discovery) - * @param brokerUrl provided broker url by user - * @return updated broker url with expected amqp protocol - */ - private static String appendMissingProtocol(String brokerUrl) { - StringBuilder newBrokerUrl = new StringBuilder(); + /** + * Append an AMQP protocol to broker url for all possible connecting options (simple, failover, discovery) + * + * @param brokerUrl provided broker url by user + * @return updated broker url with expected amqp protocol + */ + private static String appendMissingProtocol(String brokerUrl) { + StringBuilder newBrokerUrl = new StringBuilder(); - String[] brokerUrls = brokerUrl.split(","); - Pattern pattern = Pattern.compile(protocol + hostname + query); + String[] brokerUrls = brokerUrl.split(","); + Pattern pattern = Pattern.compile(protocol + hostname + query); - String tmpUrl; - for (String simpleBrokerUrl: brokerUrls) { - Matcher matcher = pattern.matcher(simpleBrokerUrl); - if (matcher.find()) { - if (matcher.group("protocol") == null) { - tmpUrl = "amqp://" + matcher.group(); - } else { - tmpUrl = matcher.group(); + String tmpUrl; + for (String simpleBrokerUrl : brokerUrls) { + Matcher matcher = pattern.matcher(simpleBrokerUrl); + if (matcher.find()) { + if (matcher.group("protocol") == null) { + tmpUrl = "amqp://" + matcher.group(); + } else { + tmpUrl = matcher.group(); + } + newBrokerUrl.append(tmpUrl).append(","); + } else { + LOG.error("Unable to parse broker-url '" + brokerUrl + "'."); + System.exit(2); + } } - newBrokerUrl.append(tmpUrl).append(","); - } else { - LOG.error("Unable to parse broker-url '" + brokerUrl + "'."); - System.exit(2); - } + newBrokerUrl.deleteCharAt(newBrokerUrl.length() - 1); + LOG.trace("FinalBrokerUrl=" + newBrokerUrl.toString()); + return newBrokerUrl.toString(); } - newBrokerUrl.deleteCharAt(newBrokerUrl.length() - 1); - LOG.trace("FinalBrokerUrl=" + newBrokerUrl.toString()); - return newBrokerUrl.toString(); - } - /** - * Method sets broker options like hostname, port, credentials, protocol. - * Also sets various simple options like transaction, & other.. - * - * @param optionName to be set to ClientOptions (broker_port, broker_host, password, transaction ..) - * @param value value of the option - * @param clientOptions ClientOptions to be used/modified - */ + /** + * Method sets broker options like hostname, port, credentials, protocol. + * Also sets various simple options like transaction, & other.. + * + * @param optionName to be set to ClientOptions (broker_port, broker_host, password, transaction ..) + * @param value value of the option + * @param clientOptions ClientOptions to be used/modified + */ - private static void checkAndSetOption(String optionName, String value, ClientOptions clientOptions) { - LOG.trace(optionName + "->" + value); - if (value != null) { - if (value.endsWith("://")) { - value = value.replace("://", ""); - } - clientOptions.getOption(optionName).setParsedValue(value); + private static void checkAndSetOption(String optionName, String value, ClientOptions clientOptions) { + LOG.trace(optionName + "->" + value); + if (value != null) { + if (value.endsWith("://")) { + value = value.replace("://", ""); + } + clientOptions.getOption(optionName).setParsedValue(value); + } } - } - /** - * Merge two maps together. Client specific values are not overridden by default common options. - * - * @param commonOpts - default options for clients - * @param clientOpts - customized options for given client - * @return client options map, filled with default common options - */ - public static List mergeOptionLists(List commonOpts, List clientOpts) { - LOG.trace("OPTS common:" + commonOpts.size() + "+ cli:" + clientOpts.size()); - for (com.redhat.mqe.lib.Option commonOption : commonOpts) { - if (!clientOpts.contains(commonOption)) { - // add default key-value into clientOpts - clientOpts.add(commonOption); - } else { - LOG.warn("Option " + commonOption + " is already present in the client map. Skip?"); - } + /** + * Merge two maps together. Client specific values are not overridden by default common options. + * + * @param commonOpts - default options for clients + * @param clientOpts - customized options for given client + * @return client options map, filled with default common options + */ + public static List mergeOptionLists(List commonOpts, List clientOpts) { + LOG.trace("OPTS common:" + commonOpts.size() + "+ cli:" + clientOpts.size()); + for (com.redhat.mqe.lib.Option commonOption : commonOpts) { + if (!clientOpts.contains(commonOption)) { + // add default key-value into clientOpts + clientOpts.add(commonOption); + } else { + LOG.warn("Option " + commonOption + " is already present in the client map. Skip?"); + } + } + return clientOpts; } - return clientOpts; - } - static void printHelp(OptionParser parser) { - try { - // TODO customize help output - parser.printHelpOn(System.out); - } catch (IOException e) { - e.printStackTrace(); - System.exit(1); + static void printHelp(OptionParser parser) { + try { + // TODO customize help output + parser.printHelpOn(System.out); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } } - } } class StringLengthComparator implements Comparator { - /** - * Sort by descending order (from the longest to the shortest). - * - * @param s1 first String - * @param s2 second String - * @return -1 if s1 is longer, 0 when equally long string, 1 if s2 is longer - */ - @Override - public int compare(String s1, String s2) { - if (s1.length() == s2.length()) return 0; - return (s1.length() > s2.length()) ? -1 : 1; - } + /** + * Sort by descending order (from the longest to the shortest). + * + * @param s1 first String + * @param s2 second String + * @return -1 if s1 is longer, 0 when equally long string, 1 if s2 is longer + */ + @Override + public int compare(String s1, String s2) { + if (s1.length() == s2.length()) return 0; + return (s1.length() > s2.length()) ? -1 : 1; + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptions.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptions.java index c70496e8..a7896a36 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptions.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ClientOptions.java @@ -30,339 +30,339 @@ */ public abstract class ClientOptions { - protected static final Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); - private static final Map translationDtestJmsMap = new HashMap(); - private final List defaultOptions = new ArrayList<>(); - private List updatedOptions = new ArrayList<>(); - static List argsAcceptingMultipleValues = new ArrayList<>(); - static List failoverProtocols = new ArrayList<>(); - static List numericArgumentValueOptionList = new ArrayList<>(); - - /* Mapping of client option to jms client is done in CoreClient.CONNECTION_TRANSLATION_MAP */ - static final String BROKER = "broker"; - static final String BROKER_URI = "broker-uri"; - static final String TRANSACTED = "transacted"; - static final String MSG_DURABLE = "msg-durable"; - static final String ADDRESS = "address"; - static final String DURATION = "duration"; - static final String DURATION_MODE = "duration-mode"; - static final String LOG_LEVEL = "log-lib"; - static final String LOG_STATS = "log-stats"; - static final String USERNAME = "conn-username"; // jms.username - static final String PASSWORD = "conn-password"; // jms.password - static final String HELP = "help"; - static final String SSN_ACK_MODE = "ssn-ack-mode"; - static final String CLOSE_SLEEP = "close-sleep"; - - static final String CON_HEARTBEAT = "conn-heartbeat"; // amqp.idleTimeout=[ms] * 1000ms - static final String CON_VHOST = "conn-vhost"; // amqp.vhost - static final String CON_SASL_MECHS = "conn-auth-mechanisms"; // amqp.saslMechanisms - static final String CON_SASL_LAYER = "conn-auth-sasl"; // amqp.saslLayer - static final String CON_MAX_FRAME_SIZE = "conn-max-frame-size"; // amqp.maxFrameSize - static final String CON_DRAIN_TIMEOUT = "conn-drain-timeout"; // amqp.drainTimeout - - static final String CON_CLIENTID = "conn-clientid"; // jms.clientID - static final String CON_ASYNC_SEND = "conn-async-send"; // jms.forceAsyncSend - static final String CON_SYNC_SEND = "conn-sync-send"; // jms.alwaysSyncSend - static final String CON_ASYNC_ACKS = "conn-async-acks"; // jms.sendAcksAsync - static final String CON_LOC_MSG_PRIO = "conn-local-msg-priority"; // jms.localMessagePriority - static final String CON_VALID_PROP_NAMES = "conn-valid-prop-names"; // jms.validatePropertyNames - - static final String CON_RECV_LOCAL_ONLY = "conn-recv-local-only"; // jms.receiveLocalOnly - static final String CON_RECV_NOWAIT_LOCAL = "conn-recv-nowait-local"; // jms.receiveNoWaitLocalOnly - - static final String CON_QUEUE_PREFIX = "conn-queue-prefix"; // jms.queuePrefix - static final String CON_TOPIC_PREFIX = "conn-topic-prefix"; // jms.topicPrefix - static final String CON_CLOSE_TIMEOUT = "conn-close-timeout"; // jms.closeTimeout - static final String CON_CONN_TIMEOUT = "conn-conn-timeout"; // jms.connectTimeout - static final String CON_CLIENTID_PREFIX = "conn-clientid-prefix"; // jms.clientIDPrefix - static final String CON_CONNID_PREFIX = "conn-connid-prefix"; // jms.connectionIDPrefix - static final String CON_POPULATE_JMSXUSERID = "conn-populate-user-id"; // jms.populateJMSXUserID - - static final String CON_PREFETCH_QUEUE = "conn-prefetch-queue"; // jms.prefetchPolicy.queuePrefetch - static final String CON_PREFETCH_TOPIC = "conn-prefetch-topic"; // jms.prefetchPolicy.topicPrefetch - static final String CON_PREFETCH_BROWSER = "conn-prefetch-browser"; // jms.prefetchPolicy.queueBrowserPrefetch - static final String CON_PREFETCH_DUR_TOPIC = "conn-prefetch-topic-dur"; // jms.prefetchPolicy.durableTopicPrefetch - static final String CON_PREFETCH_ALL = "conn-prefetch"; // jms.prefetchPolicy.all - - static final String CON_MAX_REDELIVERIES = "conn-redeliveries-max"; // jms.redeliveryPolicy.maxRedeliveries - - static final String CON_TCP_SEND_BUF_SIZE = "conn-tcp-buf-size-send"; // transport.sendBufferSize - static final String CON_TCP_RECV_BUF_SIZE = "conn-tcp-buf-size-recv"; // transport.receiveBufferSize - static final String CON_TCP_TRAFFIC_CLASS = "conn-tcp-traffic-class"; // transport.trafficClass - static final String CON_TCP_CON_TIMEOUT = "conn-tcp-conn-timeout"; // transport.connectTimeout - static final String CON_TCP_SOCK_TIMEOUT = "conn-tcp-sock-timeout"; // transport.soTimeout - static final String CON_TCP_SOCK_LINGER = "conn-tcp-sock-linger"; // transport.soLinger - static final String CON_TCP_KEEP_ALIVE = "conn-tcp-keep-alive"; // transport.tcpKeepAlive - static final String CON_TCP_NO_DELAY = "conn-tcp-no-delay"; // transport.tcpNoDelay - - static final String CON_RECONNECT = "conn-reconnect"; // enable reconnect options - static final String CON_RECONNECT_INITIAL_DELAY = "conn-reconnect-initial-delay"; // failover.initialReconnectDelay (0) - static final String CON_RECONNECT_TIMEOUT = "conn-reconnect-timeout"; // failover.reconnectDelay (10ms) - static final String CON_RECONNECT_INTERVAL = "conn-reconnect-interval"; // failover.maxReconnectDelay (30sec) - static final String CON_RECONNECT_BACKOFF = "conn-reconnect-backoff"; // failover.useReconnectBackOff (true) - static final String CON_RECONNECT_BACKOFF_MULTIPLIER = "conn-reconnect-backoff-multiplier"; // failover.reconnectBackOffMultiplier - static final String CON_RETRIES = "conn-reconnect-limit"; // failover.maxReconnectAttempts (-1) - static final String CON_RECONNECT_START_LIMIT = "conn-reconnect-start-limit"; // failover.startupMaxReconnectAttempts - static final String CON_RECONNECT_WARN_ATTEMPTS = "conn-reconnect-warn-attempts"; // failover.warnAfterReconnectAttempts - - static final String CON_SSL_KEYSTORE_LOC = "conn-ssl-keystore-location"; // transport.keyStoreLocation - static final String CON_SSL_KEYSTORE_PASS = "conn-ssl-keystore-password"; // transport.keyStorePassword - static final String CON_SSL_TRUSTSTORE_LOC = "conn-ssl-truststore-location"; // transport.trustStoreLocation - static final String CON_SSL_TRUSTSTORE_PASS = "conn-ssl-truststore-password"; // transport.trustStorePassword - static final String CON_SSL_STORE_TYPE = "conn-ssl-store-type"; // transport.storeType - static final String CON_SSL_CONTEXT_PROTOCOL = "conn-ssl-context-proto"; // transport.contextProtocol - static final String CON_SSL_ENA_CIPHERED = "conn-ssl-ena-ciphered-suites"; // transport.enabledCipherSuites - static final String CON_SSL_DIS_CIPHERED = "conn-ssl-dis-ciphered-suites"; // transport.disabledCipherSuites - static final String CON_SSL_ENA_PROTOS = "conn-ssl-ena-protos"; // transport.enabledProtocols - static final String CON_SSL_DIS_PROTOS = "conn-ssl-dis-protos"; // transport.disabledProtocols - static final String CON_SSL_TRUST_ALL = "conn-ssl-trust-all"; // transport.trustAll - static final String CON_SSL_VERIFY_HOST = "conn-ssl-verify-host"; // transport.verifyHost - static final String CON_SSL_KEYALIAS = "conn-ssl-key-alias"; // transport.keyAlias - - - // TODO Not implemented by client libraries + protected static final Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); + private static final Map translationDtestJmsMap = new HashMap(); + private final List defaultOptions = new ArrayList<>(); + private List updatedOptions = new ArrayList<>(); + static List argsAcceptingMultipleValues = new ArrayList<>(); + static List failoverProtocols = new ArrayList<>(); + static List numericArgumentValueOptionList = new ArrayList<>(); + + /* Mapping of client option to jms client is done in CoreClient.CONNECTION_TRANSLATION_MAP */ + static final String BROKER = "broker"; + static final String BROKER_URI = "broker-uri"; + static final String TRANSACTED = "transacted"; + static final String MSG_DURABLE = "msg-durable"; + static final String ADDRESS = "address"; + static final String DURATION = "duration"; + static final String DURATION_MODE = "duration-mode"; + static final String LOG_LEVEL = "log-lib"; + static final String LOG_STATS = "log-stats"; + static final String USERNAME = "conn-username"; // jms.username + static final String PASSWORD = "conn-password"; // jms.password + static final String HELP = "help"; + static final String SSN_ACK_MODE = "ssn-ack-mode"; + static final String CLOSE_SLEEP = "close-sleep"; + + static final String CON_HEARTBEAT = "conn-heartbeat"; // amqp.idleTimeout=[ms] * 1000ms + static final String CON_VHOST = "conn-vhost"; // amqp.vhost + static final String CON_SASL_MECHS = "conn-auth-mechanisms"; // amqp.saslMechanisms + static final String CON_SASL_LAYER = "conn-auth-sasl"; // amqp.saslLayer + static final String CON_MAX_FRAME_SIZE = "conn-max-frame-size"; // amqp.maxFrameSize + static final String CON_DRAIN_TIMEOUT = "conn-drain-timeout"; // amqp.drainTimeout + + static final String CON_CLIENTID = "conn-clientid"; // jms.clientID + static final String CON_ASYNC_SEND = "conn-async-send"; // jms.forceAsyncSend + static final String CON_SYNC_SEND = "conn-sync-send"; // jms.alwaysSyncSend + static final String CON_ASYNC_ACKS = "conn-async-acks"; // jms.sendAcksAsync + static final String CON_LOC_MSG_PRIO = "conn-local-msg-priority"; // jms.localMessagePriority + static final String CON_VALID_PROP_NAMES = "conn-valid-prop-names"; // jms.validatePropertyNames + + static final String CON_RECV_LOCAL_ONLY = "conn-recv-local-only"; // jms.receiveLocalOnly + static final String CON_RECV_NOWAIT_LOCAL = "conn-recv-nowait-local"; // jms.receiveNoWaitLocalOnly + + static final String CON_QUEUE_PREFIX = "conn-queue-prefix"; // jms.queuePrefix + static final String CON_TOPIC_PREFIX = "conn-topic-prefix"; // jms.topicPrefix + static final String CON_CLOSE_TIMEOUT = "conn-close-timeout"; // jms.closeTimeout + static final String CON_CONN_TIMEOUT = "conn-conn-timeout"; // jms.connectTimeout + static final String CON_CLIENTID_PREFIX = "conn-clientid-prefix"; // jms.clientIDPrefix + static final String CON_CONNID_PREFIX = "conn-connid-prefix"; // jms.connectionIDPrefix + static final String CON_POPULATE_JMSXUSERID = "conn-populate-user-id"; // jms.populateJMSXUserID + + static final String CON_PREFETCH_QUEUE = "conn-prefetch-queue"; // jms.prefetchPolicy.queuePrefetch + static final String CON_PREFETCH_TOPIC = "conn-prefetch-topic"; // jms.prefetchPolicy.topicPrefetch + static final String CON_PREFETCH_BROWSER = "conn-prefetch-browser"; // jms.prefetchPolicy.queueBrowserPrefetch + static final String CON_PREFETCH_DUR_TOPIC = "conn-prefetch-topic-dur"; // jms.prefetchPolicy.durableTopicPrefetch + static final String CON_PREFETCH_ALL = "conn-prefetch"; // jms.prefetchPolicy.all + + static final String CON_MAX_REDELIVERIES = "conn-redeliveries-max"; // jms.redeliveryPolicy.maxRedeliveries + + static final String CON_TCP_SEND_BUF_SIZE = "conn-tcp-buf-size-send"; // transport.sendBufferSize + static final String CON_TCP_RECV_BUF_SIZE = "conn-tcp-buf-size-recv"; // transport.receiveBufferSize + static final String CON_TCP_TRAFFIC_CLASS = "conn-tcp-traffic-class"; // transport.trafficClass + static final String CON_TCP_CON_TIMEOUT = "conn-tcp-conn-timeout"; // transport.connectTimeout + static final String CON_TCP_SOCK_TIMEOUT = "conn-tcp-sock-timeout"; // transport.soTimeout + static final String CON_TCP_SOCK_LINGER = "conn-tcp-sock-linger"; // transport.soLinger + static final String CON_TCP_KEEP_ALIVE = "conn-tcp-keep-alive"; // transport.tcpKeepAlive + static final String CON_TCP_NO_DELAY = "conn-tcp-no-delay"; // transport.tcpNoDelay + + static final String CON_RECONNECT = "conn-reconnect"; // enable reconnect options + static final String CON_RECONNECT_INITIAL_DELAY = "conn-reconnect-initial-delay"; // failover.initialReconnectDelay (0) + static final String CON_RECONNECT_TIMEOUT = "conn-reconnect-timeout"; // failover.reconnectDelay (10ms) + static final String CON_RECONNECT_INTERVAL = "conn-reconnect-interval"; // failover.maxReconnectDelay (30sec) + static final String CON_RECONNECT_BACKOFF = "conn-reconnect-backoff"; // failover.useReconnectBackOff (true) + static final String CON_RECONNECT_BACKOFF_MULTIPLIER = "conn-reconnect-backoff-multiplier"; // failover.reconnectBackOffMultiplier + static final String CON_RETRIES = "conn-reconnect-limit"; // failover.maxReconnectAttempts (-1) + static final String CON_RECONNECT_START_LIMIT = "conn-reconnect-start-limit"; // failover.startupMaxReconnectAttempts + static final String CON_RECONNECT_WARN_ATTEMPTS = "conn-reconnect-warn-attempts"; // failover.warnAfterReconnectAttempts + + static final String CON_SSL_KEYSTORE_LOC = "conn-ssl-keystore-location"; // transport.keyStoreLocation + static final String CON_SSL_KEYSTORE_PASS = "conn-ssl-keystore-password"; // transport.keyStorePassword + static final String CON_SSL_TRUSTSTORE_LOC = "conn-ssl-truststore-location"; // transport.trustStoreLocation + static final String CON_SSL_TRUSTSTORE_PASS = "conn-ssl-truststore-password"; // transport.trustStorePassword + static final String CON_SSL_STORE_TYPE = "conn-ssl-store-type"; // transport.storeType + static final String CON_SSL_CONTEXT_PROTOCOL = "conn-ssl-context-proto"; // transport.contextProtocol + static final String CON_SSL_ENA_CIPHERED = "conn-ssl-ena-ciphered-suites"; // transport.enabledCipherSuites + static final String CON_SSL_DIS_CIPHERED = "conn-ssl-dis-ciphered-suites"; // transport.disabledCipherSuites + static final String CON_SSL_ENA_PROTOS = "conn-ssl-ena-protos"; // transport.enabledProtocols + static final String CON_SSL_DIS_PROTOS = "conn-ssl-dis-protos"; // transport.disabledProtocols + static final String CON_SSL_TRUST_ALL = "conn-ssl-trust-all"; // transport.trustAll + static final String CON_SSL_VERIFY_HOST = "conn-ssl-verify-host"; // transport.verifyHost + static final String CON_SSL_KEYALIAS = "conn-ssl-key-alias"; // transport.keyAlias + + + // TODO Not implemented by client libraries // static final String CON_SSL_PROTOCOL = "conn-ssl-protocol"; - // These few options are not settable from outside. Client sets them up when setting parsed options. - static final String PROTOCOL = "protocol"; - static final String BROKER_HOST = "broker_host"; - static final String BROKER_PORT = "broker_port"; - static final String BROKER_OPTIONS = "broker_options"; - static final String DESTINATION_TYPE = "destination_type"; - static final String FAILOVER_PROTO = "failover"; - static final String DISCOVERY_PROTO = "discovery"; - static final String FAILOVER_URL = "failover_url"; - - /** - * S+R+? - */ - static final String TIMEOUT = "timeout"; - static final String COUNT = "count"; - static final String LOG_MSGS = "log-msgs"; - static final String TX_SIZE = "tx-size"; - static final String TX_ACTION = "tx-action"; - static final String TX_ENDLOOP_ACTION = "tx-endloop-action"; - static final String CAPACITY = "capacity"; - - /** - * RECEIVER Options - */ - static final String ACTION = "action"; - static final String SYNC_MODE = "sync-mode"; - static final String MSG_LISTENER = "msg-listener-ena"; - static final String DURABLE_SUBSCRIBER = "durable-subscriber"; - static final String UNSUBSCRIBE = "subscriber-unsubscribe"; - static final String DURABLE_SUBSCRIBER_PREFIX = "durable-subscriber-prefix"; - static final String DURABLE_SUBSCRIBER_NAME = "durable-subscriber-name"; - static final String MSG_SELECTOR = "msg-selector"; - static final String BROWSER = "recv-browse"; - static final String PROCESS_REPLY_TO = "process-reply-to"; - static final String MSG_BINARY_CONTENT_TO_FILE = "msg-binary-content-to-file"; - - /** - * SENDER - */ - static final String MSG_TTL = "msg-ttl"; - static final String MSG_PRIORITY = "msg-priority"; - static final String MSG_ID = "msg-id"; - static final String MSG_REPLY_TO = "msg-reply-to"; - static final String MSG_SUBJECT = "msg-subject"; - static final String MSG_USER_ID = "msg-user-id"; - static final String MSG_CORRELATION_ID = "msg-correlation-id"; - static final String MSG_NOTIMESTAMP = "msg-no-timestamp"; - - static final String PROPERTY_TYPE = "property-type"; - static final String MSG_PROPERTY = "msg-property"; - static final String CONTENT_TYPE = "content-type"; - static final String MSG_CONTENT = "msg-content"; - public static final String MSG_CONTENT_BINARY = "msg-content-binary"; - static final String MSG_CONTENT_TYPE = "msg-content-type"; - static final String MSG_CONTENT_FROM_FILE = "msg-content-from-file"; - static final String MSG_CONTENT_MAP_ITEM = "msg-content-map-item"; - static final String MSG_CONTENT_LIST_ITEM = "msg-content-list-item"; - - static final String MSG_GROUP_ID = "msg-group-id"; - static final String MSG_GROUP_SEQ = "msg-group-seq"; - static final String MSG_REPLY_TO_GROUP_ID = "msg-reply-to-group-id"; - - - /** - * CONNECTOR - */ - static final String OBJ_CTRL = "obj-ctrl"; - static final String Q_COUNT = "q-count"; - - /** - * QMF Options? - * TODO qmf options - */ - - public ClientOptions() { - defaultOptions.addAll(Arrays.asList( - // Options updated by parsing broker/broker-url - new com.redhat.mqe.lib.Option(PROTOCOL, "amqp"), - new com.redhat.mqe.lib.Option(BROKER_HOST, "localhost"), - new com.redhat.mqe.lib.Option(BROKER_PORT, "5672"), - new com.redhat.mqe.lib.Option(BROKER_OPTIONS, ""), - new com.redhat.mqe.lib.Option(DESTINATION_TYPE, ConnectionManager.QUEUE_OBJECT), - - new com.redhat.mqe.lib.Option(USERNAME, "", "USERNAME", "", "jms.username (not defined before host:port in qpid-jms-client)"), - new com.redhat.mqe.lib.Option(PASSWORD, "", "PASSWORD", "", "jms.password (not defined before host:port in qpid-jms-client)"), - new com.redhat.mqe.lib.Option(HELP, "h", "", "", "show this help"), - new com.redhat.mqe.lib.Option(BROKER, "b", "HOST:5672", "amqp://localhost:5672", "url broker to connect to, default"), - new com.redhat.mqe.lib.Option(BROKER_URI, "", "AmqpQpidJmsURL", "amqp://localhost:5672[[?conOpt=val]&conOpt=val]", - "AMQP JMS QPID specific broker uri. NOTE: This options overrides everything related to broker & connection options. " + - "It is used as exactly as provided!"), - new com.redhat.mqe.lib.Option(LOG_LEVEL, "", "LEVEL", "info", "logging level of the client. trace/debug/info/warn/error"), - new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "INFO", "report various statistic/debug information"), // ? - new com.redhat.mqe.lib.Option(SSN_ACK_MODE, "", "ACKMODE", "auto", "session acknowledge mode auto/client/dups_ok/(individual)"), - new com.redhat.mqe.lib.Option(CLOSE_SLEEP, "", "CSLEEP", "0", "sleep before publisher/subscriber/session/connection.close() in floating seconds"), - - new com.redhat.mqe.lib.Option(CON_HEARTBEAT, "", "SECONDS", "60", "frequency of heartbeat messages (in seconds)"), - new com.redhat.mqe.lib.Option(CON_VHOST, "", "VHOST", "", "virtual hostname to connect to. (Default: main from URI)"), - new com.redhat.mqe.lib.Option(CON_SASL_LAYER, "", "ENABLED", "true", "choose whether SASL layer should be used"), - new com.redhat.mqe.lib.Option(CON_SASL_MECHS, "", "MECHS", "all", "comma separated list of SASL mechanisms allowed by client for authentication (plain/anonymous/external/cram-md5?/digest-md5?)"), - new com.redhat.mqe.lib.Option(CON_MAX_FRAME_SIZE, "", "BYTES", "1048576", "The max-frame-size value in bytes that is advertised to the peer. Default is 1048576"), - new com.redhat.mqe.lib.Option(CON_DRAIN_TIMEOUT, "", "MS", "60000", "The time in milliseconds that the client will wait for a response from the remote when a drain request is made. (Default 60000ms)"), - - new com.redhat.mqe.lib.Option(CON_CLIENTID, "", "CLIENTID", "", "clientID value that is applied to the connection."), - new com.redhat.mqe.lib.Option(CON_ASYNC_SEND, "", "ENABLED", "false", "send all messages asynchronously (if false only non-persistent and transacted are send asynchronously"), - new com.redhat.mqe.lib.Option(CON_SYNC_SEND, "", "ENABLED", "false", "send all messages synchronously"), - new com.redhat.mqe.lib.Option(CON_ASYNC_ACKS, "", "ENABLED", "false", "causes all Message acknowledgments to be sent asynchronously"), - new com.redhat.mqe.lib.Option(CON_LOC_MSG_PRIO, "", "ENABLED", "false", "prefetched messages are reordered locally based on their given priority"), - new com.redhat.mqe.lib.Option(CON_VALID_PROP_NAMES, "", "ENABLED", "true", "message property names should be validated as valid Java identifiers"), - - new com.redhat.mqe.lib.Option(CON_RECV_LOCAL_ONLY, "", "ENABLED", "false", "if enabled receive calls with a timeout will only check a consumers local message buffer"), - new com.redhat.mqe.lib.Option(CON_RECV_NOWAIT_LOCAL, "", "ENABLED", "false", "if enabled receiveNoWait calls will only check a consumers local message buffer"), - - new com.redhat.mqe.lib.Option(CON_QUEUE_PREFIX, "", "PREFIX", "", "optional prefix value added to the name of any Queue created from a JMS Session"), - new com.redhat.mqe.lib.Option(CON_TOPIC_PREFIX, "", "PREFIX", "", "optional prefix value added to the name of any Topic created from a JMS Session."), - new com.redhat.mqe.lib.Option(CON_CLOSE_TIMEOUT, "", "TIMEOUT", "15", "timeout value that controls how long the client waits on Connection close before returning"), - new com.redhat.mqe.lib.Option(CON_CONN_TIMEOUT, "", "TIMEOUT", "15", "timeout value that controls how long the client waits on Connection establishment before returning with an error"), - new com.redhat.mqe.lib.Option(CON_CLIENTID_PREFIX, "", "PREFIX", "ID:", "client ID prefix for new connections"), - new com.redhat.mqe.lib.Option(CON_CONNID_PREFIX, "", "PREFIX", "ID:", "connection ID prefix used for a new connections. Usable for tracking connections in logs"), - new com.redhat.mqe.lib.Option(CON_POPULATE_JMSXUSERID, "", "ENABLED", "false", "populate the JMSXUserID for each sent message using authenticated username from connection"), - - new com.redhat.mqe.lib.Option(CON_MAX_REDELIVERIES, "", "COUNT", "-1", "maximum number of allowed message redeliveries"), - new com.redhat.mqe.lib.Option(CON_PREFETCH_QUEUE, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), - new com.redhat.mqe.lib.Option(CON_PREFETCH_TOPIC, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), - new com.redhat.mqe.lib.Option(CON_PREFETCH_BROWSER, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), - new com.redhat.mqe.lib.Option(CON_PREFETCH_DUR_TOPIC, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), - new com.redhat.mqe.lib.Option(CON_PREFETCH_ALL, "", "COUNT", "1000", "set prefetch values to all prefetch options"), - - new com.redhat.mqe.lib.Option(CON_RECONNECT, "", "ENABLED", "false", "enable default failover reconnect"), - new com.redhat.mqe.lib.Option(CON_RETRIES, "", "COUNT", "-1", "retry to connect to the broker that many times"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_TIMEOUT, "", "MS", "10", "delay between successive reconnection attempts; constant if backoff is off"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_INTERVAL, "", "SEC", "30", "maximum time that client will wait before next reconnect. Used only when backoff is on"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_BACKOFF, "", "ENABLED", "true", "choose to use backoff multiplier or not"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_BACKOFF_MULTIPLIER, "", "VALUE", "2.0", "backoff multiplier for reconnect intervals"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_START_LIMIT, "", "INTERVAL", "-1", "For a client that has never connected to a remote peer before, this sets " + - "the number of attempts made to connect before reporting the connection as failed. The default is value of maxReconnectAttempts"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_INITIAL_DELAY, "", "DELAY", "0", "delay the client will wait before the first attempt to reconnect to a remote peer"), - new com.redhat.mqe.lib.Option(CON_RECONNECT_WARN_ATTEMPTS, "", "ATTEMPTS", "10", "that often the client will log a message indicating that failover reconnection is being attempted"), - - new com.redhat.mqe.lib.Option(CON_SSL_KEYSTORE_LOC, "", "LOC", "", "default is to read from the system property \"javax.net.ssl.keyStore\""), - new com.redhat.mqe.lib.Option(CON_SSL_KEYSTORE_PASS, "", "PASS", "", "default is to read from the system property \"javax.net.ssl.keyStorePassword\""), - new com.redhat.mqe.lib.Option(CON_SSL_TRUSTSTORE_LOC, "", "LOC", "", "default is to read from the system property \"javax.net.ssl.trustStore\""), - new com.redhat.mqe.lib.Option(CON_SSL_TRUSTSTORE_PASS, "", "PASS", "", "default is to read from the system property \"javax.net.ssl.keyStorePassword\""), - new com.redhat.mqe.lib.Option(CON_SSL_STORE_TYPE, "", "TYPE", "JKS", "store type"), - new com.redhat.mqe.lib.Option(CON_SSL_CONTEXT_PROTOCOL, "", "PROTOCOL", "TLS", "protocol argument used when getting an SSLContext"), - new com.redhat.mqe.lib.Option(CON_SSL_ENA_CIPHERED, "", "SUITES", "", "enabled cipher suites (comma separated list); disabled ciphers are removed from this list."), - new com.redhat.mqe.lib.Option(CON_SSL_DIS_CIPHERED, "", "SUITES", "", "disabled cipher suites (comma separated list)"), - new com.redhat.mqe.lib.Option(CON_SSL_ENA_PROTOS, "", "PROTOCOLS", "", "enabled protocols (comma separated list). No default, meaning the context default protocols are used"), - new com.redhat.mqe.lib.Option(CON_SSL_DIS_PROTOS, "", "PROTOCOLS", "SSLv2Hello,SSLv3", "disabled protocols (comma separated list)"), - new com.redhat.mqe.lib.Option(CON_SSL_TRUST_ALL, "", "ENABLED", "false", ""), - new com.redhat.mqe.lib.Option(CON_SSL_VERIFY_HOST, "", "ENABLED", "true", ""), - new com.redhat.mqe.lib.Option(CON_SSL_KEYALIAS, "", "ALIAS", "", "alias to use when selecting a keypair from the keystore if required to send a client certificate to the server"), - - new com.redhat.mqe.lib.Option(CON_TCP_SEND_BUF_SIZE, "", "SIZE", "64", "tcp send buffer size in kilobytes"), - new com.redhat.mqe.lib.Option(CON_TCP_RECV_BUF_SIZE, "", "SIZE", "64", "tcp receive buffer size in kilobytes"), - new com.redhat.mqe.lib.Option(CON_TCP_TRAFFIC_CLASS, "", "CLASS?", "0", "?tcp traffic class"), - new com.redhat.mqe.lib.Option(CON_TCP_CON_TIMEOUT, "", "TIMEOUT", "60", "tcp connection timeout in seconds"), - new com.redhat.mqe.lib.Option(CON_TCP_SOCK_TIMEOUT, "", "TIMEOUT", "-1", "?tcp socket timeout in (-1 disabled?)"), - new com.redhat.mqe.lib.Option(CON_TCP_SOCK_LINGER, "", "TIMEOUT", "-1", "?tcp socket linger timeout"), - new com.redhat.mqe.lib.Option(CON_TCP_KEEP_ALIVE, "", "ENABLED", "false", "send tcp keep alive packets"), - new com.redhat.mqe.lib.Option(CON_TCP_NO_DELAY, "", "ENABLED", "true", "use tcp_nodelay (automatic concatenation of small packets into bigger frames)"), - - new com.redhat.mqe.lib.Option(TRANSACTED, "false"), - new com.redhat.mqe.lib.Option(MSG_DURABLE, "false"), - new com.redhat.mqe.lib.Option(DURATION, "0"), - new com.redhat.mqe.lib.Option(FAILOVER_URL, "") - )); - translationDtestJmsMap.put("", ""); - - argsAcceptingMultipleValues.addAll(Arrays.asList(MSG_CONTENT_LIST_ITEM, MSG_CONTENT_MAP_ITEM, MSG_PROPERTY)); - failoverProtocols.addAll(Arrays.asList(FAILOVER_PROTO, DISCOVERY_PROTO)); - } - - /** - * Check whether this option is valid for client. - * - * @param option option name to look up in optionsMap - * @return true, if this option is valid for given client. - */ - - public boolean isValidOption(com.redhat.mqe.lib.Option option) { - if (option == null) { - throw new IllegalArgumentException("Argument is null!"); + // These few options are not settable from outside. Client sets them up when setting parsed options. + static final String PROTOCOL = "protocol"; + static final String BROKER_HOST = "broker_host"; + static final String BROKER_PORT = "broker_port"; + static final String BROKER_OPTIONS = "broker_options"; + static final String DESTINATION_TYPE = "destination_type"; + static final String FAILOVER_PROTO = "failover"; + static final String DISCOVERY_PROTO = "discovery"; + static final String FAILOVER_URL = "failover_url"; + + /** + * S+R+? + */ + static final String TIMEOUT = "timeout"; + static final String COUNT = "count"; + static final String LOG_MSGS = "log-msgs"; + static final String TX_SIZE = "tx-size"; + static final String TX_ACTION = "tx-action"; + static final String TX_ENDLOOP_ACTION = "tx-endloop-action"; + static final String CAPACITY = "capacity"; + + /** + * RECEIVER Options + */ + static final String ACTION = "action"; + static final String SYNC_MODE = "sync-mode"; + static final String MSG_LISTENER = "msg-listener-ena"; + static final String DURABLE_SUBSCRIBER = "durable-subscriber"; + static final String UNSUBSCRIBE = "subscriber-unsubscribe"; + static final String DURABLE_SUBSCRIBER_PREFIX = "durable-subscriber-prefix"; + static final String DURABLE_SUBSCRIBER_NAME = "durable-subscriber-name"; + static final String MSG_SELECTOR = "msg-selector"; + static final String BROWSER = "recv-browse"; + static final String PROCESS_REPLY_TO = "process-reply-to"; + static final String MSG_BINARY_CONTENT_TO_FILE = "msg-binary-content-to-file"; + + /** + * SENDER + */ + static final String MSG_TTL = "msg-ttl"; + static final String MSG_PRIORITY = "msg-priority"; + static final String MSG_ID = "msg-id"; + static final String MSG_REPLY_TO = "msg-reply-to"; + static final String MSG_SUBJECT = "msg-subject"; + static final String MSG_USER_ID = "msg-user-id"; + static final String MSG_CORRELATION_ID = "msg-correlation-id"; + static final String MSG_NOTIMESTAMP = "msg-no-timestamp"; + + static final String PROPERTY_TYPE = "property-type"; + static final String MSG_PROPERTY = "msg-property"; + static final String CONTENT_TYPE = "content-type"; + static final String MSG_CONTENT = "msg-content"; + public static final String MSG_CONTENT_BINARY = "msg-content-binary"; + static final String MSG_CONTENT_TYPE = "msg-content-type"; + static final String MSG_CONTENT_FROM_FILE = "msg-content-from-file"; + static final String MSG_CONTENT_MAP_ITEM = "msg-content-map-item"; + static final String MSG_CONTENT_LIST_ITEM = "msg-content-list-item"; + + static final String MSG_GROUP_ID = "msg-group-id"; + static final String MSG_GROUP_SEQ = "msg-group-seq"; + static final String MSG_REPLY_TO_GROUP_ID = "msg-reply-to-group-id"; + + + /** + * CONNECTOR + */ + static final String OBJ_CTRL = "obj-ctrl"; + static final String Q_COUNT = "q-count"; + + /** + * QMF Options? + * TODO qmf options + */ + + public ClientOptions() { + defaultOptions.addAll(Arrays.asList( + // Options updated by parsing broker/broker-url + new com.redhat.mqe.lib.Option(PROTOCOL, "amqp"), + new com.redhat.mqe.lib.Option(BROKER_HOST, "localhost"), + new com.redhat.mqe.lib.Option(BROKER_PORT, "5672"), + new com.redhat.mqe.lib.Option(BROKER_OPTIONS, ""), + new com.redhat.mqe.lib.Option(DESTINATION_TYPE, ConnectionManager.QUEUE_OBJECT), + + new com.redhat.mqe.lib.Option(USERNAME, "", "USERNAME", "", "jms.username (not defined before host:port in qpid-jms-client)"), + new com.redhat.mqe.lib.Option(PASSWORD, "", "PASSWORD", "", "jms.password (not defined before host:port in qpid-jms-client)"), + new com.redhat.mqe.lib.Option(HELP, "h", "", "", "show this help"), + new com.redhat.mqe.lib.Option(BROKER, "b", "HOST:5672", "amqp://localhost:5672", "url broker to connect to, default"), + new com.redhat.mqe.lib.Option(BROKER_URI, "", "AmqpQpidJmsURL", "amqp://localhost:5672[[?conOpt=val]&conOpt=val]", + "AMQP JMS QPID specific broker uri. NOTE: This options overrides everything related to broker & connection options. " + + "It is used as exactly as provided!"), + new com.redhat.mqe.lib.Option(LOG_LEVEL, "", "LEVEL", "info", "logging level of the client. trace/debug/info/warn/error"), + new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "INFO", "report various statistic/debug information"), // ? + new com.redhat.mqe.lib.Option(SSN_ACK_MODE, "", "ACKMODE", "auto", "session acknowledge mode auto/client/dups_ok/(individual)"), + new com.redhat.mqe.lib.Option(CLOSE_SLEEP, "", "CSLEEP", "0", "sleep before publisher/subscriber/session/connection.close() in floating seconds"), + + new com.redhat.mqe.lib.Option(CON_HEARTBEAT, "", "SECONDS", "60", "frequency of heartbeat messages (in seconds)"), + new com.redhat.mqe.lib.Option(CON_VHOST, "", "VHOST", "", "virtual hostname to connect to. (Default: main from URI)"), + new com.redhat.mqe.lib.Option(CON_SASL_LAYER, "", "ENABLED", "true", "choose whether SASL layer should be used"), + new com.redhat.mqe.lib.Option(CON_SASL_MECHS, "", "MECHS", "all", "comma separated list of SASL mechanisms allowed by client for authentication (plain/anonymous/external/cram-md5?/digest-md5?)"), + new com.redhat.mqe.lib.Option(CON_MAX_FRAME_SIZE, "", "BYTES", "1048576", "The max-frame-size value in bytes that is advertised to the peer. Default is 1048576"), + new com.redhat.mqe.lib.Option(CON_DRAIN_TIMEOUT, "", "MS", "60000", "The time in milliseconds that the client will wait for a response from the remote when a drain request is made. (Default 60000ms)"), + + new com.redhat.mqe.lib.Option(CON_CLIENTID, "", "CLIENTID", "", "clientID value that is applied to the connection."), + new com.redhat.mqe.lib.Option(CON_ASYNC_SEND, "", "ENABLED", "false", "send all messages asynchronously (if false only non-persistent and transacted are send asynchronously"), + new com.redhat.mqe.lib.Option(CON_SYNC_SEND, "", "ENABLED", "false", "send all messages synchronously"), + new com.redhat.mqe.lib.Option(CON_ASYNC_ACKS, "", "ENABLED", "false", "causes all Message acknowledgments to be sent asynchronously"), + new com.redhat.mqe.lib.Option(CON_LOC_MSG_PRIO, "", "ENABLED", "false", "prefetched messages are reordered locally based on their given priority"), + new com.redhat.mqe.lib.Option(CON_VALID_PROP_NAMES, "", "ENABLED", "true", "message property names should be validated as valid Java identifiers"), + + new com.redhat.mqe.lib.Option(CON_RECV_LOCAL_ONLY, "", "ENABLED", "false", "if enabled receive calls with a timeout will only check a consumers local message buffer"), + new com.redhat.mqe.lib.Option(CON_RECV_NOWAIT_LOCAL, "", "ENABLED", "false", "if enabled receiveNoWait calls will only check a consumers local message buffer"), + + new com.redhat.mqe.lib.Option(CON_QUEUE_PREFIX, "", "PREFIX", "", "optional prefix value added to the name of any Queue created from a JMS Session"), + new com.redhat.mqe.lib.Option(CON_TOPIC_PREFIX, "", "PREFIX", "", "optional prefix value added to the name of any Topic created from a JMS Session."), + new com.redhat.mqe.lib.Option(CON_CLOSE_TIMEOUT, "", "TIMEOUT", "15", "timeout value that controls how long the client waits on Connection close before returning"), + new com.redhat.mqe.lib.Option(CON_CONN_TIMEOUT, "", "TIMEOUT", "15", "timeout value that controls how long the client waits on Connection establishment before returning with an error"), + new com.redhat.mqe.lib.Option(CON_CLIENTID_PREFIX, "", "PREFIX", "ID:", "client ID prefix for new connections"), + new com.redhat.mqe.lib.Option(CON_CONNID_PREFIX, "", "PREFIX", "ID:", "connection ID prefix used for a new connections. Usable for tracking connections in logs"), + new com.redhat.mqe.lib.Option(CON_POPULATE_JMSXUSERID, "", "ENABLED", "false", "populate the JMSXUserID for each sent message using authenticated username from connection"), + + new com.redhat.mqe.lib.Option(CON_MAX_REDELIVERIES, "", "COUNT", "-1", "maximum number of allowed message redeliveries"), + new com.redhat.mqe.lib.Option(CON_PREFETCH_QUEUE, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), + new com.redhat.mqe.lib.Option(CON_PREFETCH_TOPIC, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), + new com.redhat.mqe.lib.Option(CON_PREFETCH_BROWSER, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), + new com.redhat.mqe.lib.Option(CON_PREFETCH_DUR_TOPIC, "", "COUNT", "1000", "number of messages which can be held in a prefetch buffer"), + new com.redhat.mqe.lib.Option(CON_PREFETCH_ALL, "", "COUNT", "1000", "set prefetch values to all prefetch options"), + + new com.redhat.mqe.lib.Option(CON_RECONNECT, "", "ENABLED", "false", "enable default failover reconnect"), + new com.redhat.mqe.lib.Option(CON_RETRIES, "", "COUNT", "-1", "retry to connect to the broker that many times"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_TIMEOUT, "", "MS", "10", "delay between successive reconnection attempts; constant if backoff is off"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_INTERVAL, "", "SEC", "30", "maximum time that client will wait before next reconnect. Used only when backoff is on"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_BACKOFF, "", "ENABLED", "true", "choose to use backoff multiplier or not"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_BACKOFF_MULTIPLIER, "", "VALUE", "2.0", "backoff multiplier for reconnect intervals"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_START_LIMIT, "", "INTERVAL", "-1", "For a client that has never connected to a remote peer before, this sets " + + "the number of attempts made to connect before reporting the connection as failed. The default is value of maxReconnectAttempts"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_INITIAL_DELAY, "", "DELAY", "0", "delay the client will wait before the first attempt to reconnect to a remote peer"), + new com.redhat.mqe.lib.Option(CON_RECONNECT_WARN_ATTEMPTS, "", "ATTEMPTS", "10", "that often the client will log a message indicating that failover reconnection is being attempted"), + + new com.redhat.mqe.lib.Option(CON_SSL_KEYSTORE_LOC, "", "LOC", "", "default is to read from the system property \"javax.net.ssl.keyStore\""), + new com.redhat.mqe.lib.Option(CON_SSL_KEYSTORE_PASS, "", "PASS", "", "default is to read from the system property \"javax.net.ssl.keyStorePassword\""), + new com.redhat.mqe.lib.Option(CON_SSL_TRUSTSTORE_LOC, "", "LOC", "", "default is to read from the system property \"javax.net.ssl.trustStore\""), + new com.redhat.mqe.lib.Option(CON_SSL_TRUSTSTORE_PASS, "", "PASS", "", "default is to read from the system property \"javax.net.ssl.keyStorePassword\""), + new com.redhat.mqe.lib.Option(CON_SSL_STORE_TYPE, "", "TYPE", "JKS", "store type"), + new com.redhat.mqe.lib.Option(CON_SSL_CONTEXT_PROTOCOL, "", "PROTOCOL", "TLS", "protocol argument used when getting an SSLContext"), + new com.redhat.mqe.lib.Option(CON_SSL_ENA_CIPHERED, "", "SUITES", "", "enabled cipher suites (comma separated list); disabled ciphers are removed from this list."), + new com.redhat.mqe.lib.Option(CON_SSL_DIS_CIPHERED, "", "SUITES", "", "disabled cipher suites (comma separated list)"), + new com.redhat.mqe.lib.Option(CON_SSL_ENA_PROTOS, "", "PROTOCOLS", "", "enabled protocols (comma separated list). No default, meaning the context default protocols are used"), + new com.redhat.mqe.lib.Option(CON_SSL_DIS_PROTOS, "", "PROTOCOLS", "SSLv2Hello,SSLv3", "disabled protocols (comma separated list)"), + new com.redhat.mqe.lib.Option(CON_SSL_TRUST_ALL, "", "ENABLED", "false", ""), + new com.redhat.mqe.lib.Option(CON_SSL_VERIFY_HOST, "", "ENABLED", "true", ""), + new com.redhat.mqe.lib.Option(CON_SSL_KEYALIAS, "", "ALIAS", "", "alias to use when selecting a keypair from the keystore if required to send a client certificate to the server"), + + new com.redhat.mqe.lib.Option(CON_TCP_SEND_BUF_SIZE, "", "SIZE", "64", "tcp send buffer size in kilobytes"), + new com.redhat.mqe.lib.Option(CON_TCP_RECV_BUF_SIZE, "", "SIZE", "64", "tcp receive buffer size in kilobytes"), + new com.redhat.mqe.lib.Option(CON_TCP_TRAFFIC_CLASS, "", "CLASS?", "0", "?tcp traffic class"), + new com.redhat.mqe.lib.Option(CON_TCP_CON_TIMEOUT, "", "TIMEOUT", "60", "tcp connection timeout in seconds"), + new com.redhat.mqe.lib.Option(CON_TCP_SOCK_TIMEOUT, "", "TIMEOUT", "-1", "?tcp socket timeout in (-1 disabled?)"), + new com.redhat.mqe.lib.Option(CON_TCP_SOCK_LINGER, "", "TIMEOUT", "-1", "?tcp socket linger timeout"), + new com.redhat.mqe.lib.Option(CON_TCP_KEEP_ALIVE, "", "ENABLED", "false", "send tcp keep alive packets"), + new com.redhat.mqe.lib.Option(CON_TCP_NO_DELAY, "", "ENABLED", "true", "use tcp_nodelay (automatic concatenation of small packets into bigger frames)"), + + new com.redhat.mqe.lib.Option(TRANSACTED, "false"), + new com.redhat.mqe.lib.Option(MSG_DURABLE, "false"), + new com.redhat.mqe.lib.Option(DURATION, "0"), + new com.redhat.mqe.lib.Option(FAILOVER_URL, "") + )); + translationDtestJmsMap.put("", ""); + + argsAcceptingMultipleValues.addAll(Arrays.asList(MSG_CONTENT_LIST_ITEM, MSG_CONTENT_MAP_ITEM, MSG_PROPERTY)); + failoverProtocols.addAll(Arrays.asList(FAILOVER_PROTO, DISCOVERY_PROTO)); } - return defaultOptions.contains(option); - } - - /** - * Get defaultValue for given option. - * - * @param name get defaultValue for this option - * @return Object - */ - public abstract com.redhat.mqe.lib.Option getOption(String name); - - /** - * Method for getting default values for given client. - * - * @return Map of default options for given client - */ - public abstract List getClientDefaultOptions(); - - /** - * Get list of actual/updated client options. - * - * @return current list of updated client options - */ - public abstract List getClientOptions(); - - public List getDefaultOptions() { - return defaultOptions; - } - - /** - * Method returns the map of parsed (updated) client Options, without - * the default options. - * Map contains the mapping as optionName:Option. - * OptionName keys are all defined in ClientOptions class. - * - * @return map of option names and client Options which has been - * modified by the user command line input. - */ - public Map getUpdatedOptionsMap() { - Map updatedOptionsMap = new HashMap<>(); - for (com.redhat.mqe.lib.Option option : updatedOptions) { - updatedOptionsMap.put(option.getName(), option); + + /** + * Check whether this option is valid for client. + * + * @param option option name to look up in optionsMap + * @return true, if this option is valid for given client. + */ + + public boolean isValidOption(com.redhat.mqe.lib.Option option) { + if (option == null) { + throw new IllegalArgumentException("Argument is null!"); + } + return defaultOptions.contains(option); + } + + /** + * Get defaultValue for given option. + * + * @param name get defaultValue for this option + * @return Object + */ + public abstract com.redhat.mqe.lib.Option getOption(String name); + + /** + * Method for getting default values for given client. + * + * @return Map of default options for given client + */ + public abstract List getClientDefaultOptions(); + + /** + * Get list of actual/updated client options. + * + * @return current list of updated client options + */ + public abstract List getClientOptions(); + + public List getDefaultOptions() { + return defaultOptions; + } + + /** + * Method returns the map of parsed (updated) client Options, without + * the default options. + * Map contains the mapping as optionName:Option. + * OptionName keys are all defined in ClientOptions class. + * + * @return map of option names and client Options which has been + * modified by the user command line input. + */ + public Map getUpdatedOptionsMap() { + Map updatedOptionsMap = new HashMap<>(); + for (com.redhat.mqe.lib.Option option : updatedOptions) { + updatedOptionsMap.put(option.getName(), option); + } + return updatedOptionsMap; } - return updatedOptionsMap; - } - public List getUpdatedOptions() { - return updatedOptions; - } + public List getUpdatedOptions() { + return updatedOptions; + } - public void setUpdatedOptions(List updatedOptions) { - this.updatedOptions = updatedOptions; - } + public void setUpdatedOptions(List updatedOptions) { + this.updatedOptions = updatedOptions; + } - public static void addNumericArgumentValueOptionList(com.redhat.mqe.lib.Option option) { - numericArgumentValueOptionList.add(option); - } + public static void addNumericArgumentValueOptionList(com.redhat.mqe.lib.Option option) { + numericArgumentValueOptionList.add(option); + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java index a3805537..fe53127d 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectionManager.java @@ -33,182 +33,182 @@ import javax.naming.NamingException; public class ConnectionManager { - private ConnectionFactory factory; - private Context context; - private Destination destination; - private Connection connection; - private String customConnectionFactory = "connectionfactory.amqFactory"; - private String customQueue = "queue.amqQueue"; - private String customTopic = "topic.amqTopic"; - private String destinationQueue = "amqQueue"; - private String destinationTopic = "amqTopic"; - String connectionFactory = "amqFactory"; // default amqp://localhost:5672 - String password; - String queueOrTopic = "amqQueue"; - String username; - static final String QUEUE_OBJECT = "javax.jms.Queue"; - static final String TOPIC_OBJECT = "javax.jms.Topic"; - private static final String AMQ_INITIAL_CONTEXT = "org.apache.qpid.jms.jndi.JmsInitialContextFactory"; - private static final String QPID_INITIAL_CONTEXT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory"; - - private static final String EXTERNAL_JNDI_PROPERTY = "aac1.jndi"; - private Logger LOG = LoggerFactory.getLogger(ConnectionManager.class.getName()); - - ConnectionManager(ClientOptions clientOptions, String connectionFactory) { - if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue()) { - username = clientOptions.getOption(ClientOptions.USERNAME).getValue(); - } - if (clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { - password = clientOptions.getOption(ClientOptions.PASSWORD).getValue(); - } - try { - Properties props = new Properties(); - String jndiFilePath; - if ((jndiFilePath = System.getProperty(EXTERNAL_JNDI_PROPERTY)) != null) { - // load property file from an absolute path to the file - try (FileInputStream fileInputStream = new FileInputStream(new File(jndiFilePath))) { - props.load(fileInputStream); + private ConnectionFactory factory; + private Context context; + private Destination destination; + private Connection connection; + private String customConnectionFactory = "connectionfactory.amqFactory"; + private String customQueue = "queue.amqQueue"; + private String customTopic = "topic.amqTopic"; + private String destinationQueue = "amqQueue"; + private String destinationTopic = "amqTopic"; + String connectionFactory = "amqFactory"; // default amqp://localhost:5672 + String password; + String queueOrTopic = "amqQueue"; + String username; + static final String QUEUE_OBJECT = "javax.jms.Queue"; + static final String TOPIC_OBJECT = "javax.jms.Topic"; + private static final String AMQ_INITIAL_CONTEXT = "org.apache.qpid.jms.jndi.JmsInitialContextFactory"; + private static final String QPID_INITIAL_CONTEXT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory"; + + private static final String EXTERNAL_JNDI_PROPERTY = "aac1.jndi"; + private Logger LOG = LoggerFactory.getLogger(ConnectionManager.class.getName()); + + ConnectionManager(ClientOptions clientOptions, String connectionFactory) { + if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue()) { + username = clientOptions.getOption(ClientOptions.USERNAME).getValue(); } - } else { - // fallback to use resources/jndi.properties file - jndiFilePath = "/jndi.properties"; - try (InputStream inputStream = this.getClass().getResourceAsStream(jndiFilePath)) { - props.load(inputStream); + if (clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { + password = clientOptions.getOption(ClientOptions.PASSWORD).getValue(); } - } - if (connectionFactory.contains("://")) { - // override connectionFactory by this option in jndi/properties - props.setProperty(customConnectionFactory, connectionFactory); - } + try { + Properties props = new Properties(); + String jndiFilePath; + if ((jndiFilePath = System.getProperty(EXTERNAL_JNDI_PROPERTY)) != null) { + // load property file from an absolute path to the file + try (FileInputStream fileInputStream = new FileInputStream(new File(jndiFilePath))) { + props.load(fileInputStream); + } + } else { + // fallback to use resources/jndi.properties file + jndiFilePath = "/jndi.properties"; + try (InputStream inputStream = this.getClass().getResourceAsStream(jndiFilePath)) { + props.load(inputStream); + } + } + if (connectionFactory.contains("://")) { + // override connectionFactory by this option in jndi/properties + props.setProperty(customConnectionFactory, connectionFactory); + } /* TODO if external JNDI is supported, how to read/create Provider objects from it? if (externalJNDI) { load properties, search for queue/topic property & use it } else { */ - context = new InitialContext(props); - factory = (ConnectionFactory) context.lookup(this.connectionFactory); - - if (clientOptions.getOption(ClientOptions.DESTINATION_TYPE).getValue().equals(TOPIC_OBJECT)) { - destination = createTopic(clientOptions.getOption(ClientOptions.ADDRESS).getValue()); - } else if (clientOptions.getOption(ClientOptions.DESTINATION_TYPE).getValue().equals(QUEUE_OBJECT)) { - destination = createQueue(clientOptions.getOption(ClientOptions.ADDRESS).getValue()); - } else { - // reserved for future other destination types - LOG.warn("Not sure what type of Destination to create. Falling back to Destination"); - destination = (Destination) context.lookup(this.queueOrTopic); - } - - LOG.debug("Connection=" + connectionFactory); - LOG.trace("Destination=" + destination); - if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue() - || (username == null && password == null)) { + context = new InitialContext(props); + factory = (ConnectionFactory) context.lookup(this.connectionFactory); + + if (clientOptions.getOption(ClientOptions.DESTINATION_TYPE).getValue().equals(TOPIC_OBJECT)) { + destination = createTopic(clientOptions.getOption(ClientOptions.ADDRESS).getValue()); + } else if (clientOptions.getOption(ClientOptions.DESTINATION_TYPE).getValue().equals(QUEUE_OBJECT)) { + destination = createQueue(clientOptions.getOption(ClientOptions.ADDRESS).getValue()); + } else { + // reserved for future other destination types + LOG.warn("Not sure what type of Destination to create. Falling back to Destination"); + destination = (Destination) context.lookup(this.queueOrTopic); + } + + LOG.debug("Connection=" + connectionFactory); + LOG.trace("Destination=" + destination); + if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue() + || (username == null && password == null)) { // || CoreClient.isAMQClient()) { this will work for Qpid JMS AMQP Client as well, but we will be nicer - connection = factory.createConnection(); - } else { - LOG.trace("Using credentials " + username + ":" + password); - connection = factory.createConnection(username, password); - } - - connection.setExceptionListener(new MessagingExceptionListener()); - } catch (IOException | NamingException | JMSException e) { - LOG.error(e.getMessage()); - e.printStackTrace(); - System.exit(1); + connection = factory.createConnection(); + } else { + LOG.trace("Using credentials " + username + ":" + password); + connection = factory.createConnection(username, password); + } + + connection.setExceptionListener(new MessagingExceptionListener()); + } catch (IOException | NamingException | JMSException e) { + LOG.error(e.getMessage()); + e.printStackTrace(); + System.exit(1); + } } - } - - Connection getConnection() { - return this.connection; - } - - Destination getDestination() { - return destination; - } - - /** - * @param connectionFactory - often referred to as broker url - */ - void setConnectionFactory(String connectionFactory) { - this.connectionFactory = connectionFactory; - } - - /** - * @param queueOrTopic - destination can be either queue or topic - */ - void setDestinationName(String queueOrTopic) { - this.queueOrTopic = queueOrTopic; - } - - /** - * MessagingExceptionListener is created for each connection made. - */ - class MessagingExceptionListener implements ExceptionListener { - @Override - public void onException(JMSException e) { - LOG.error("ExceptionListener error detected! \n{}\n{}", e.getMessage(), e.getCause()); - e.printStackTrace(); - System.exit(1); + + Connection getConnection() { + return this.connection; } - } - - /** - * Creates a destination for a specified name. - * - * @param destination for which destination is to be created. - * @return created Destination object - */ - Destination createDestination(String destination) { - return (Destination) createJMSProviderObject("destination", destination); - } - - /** - * Create queue object - * - * @param queueName name of the queue to be created - * @return created Queue object - */ - Queue createQueue(String queueName) { - return (Queue) createJMSProviderObject("queue", queueName); - } - - /** - * Create topic object - * - * @param topicName name of the topic to be created - * @return created Topic object - */ - Topic createTopic(String topicName) { - return (Topic) createJMSProviderObject("topic", topicName); - } - - /** - * Creates an object using qpid/amq initial context factory. - * - * @param className can be any of the qpid/amq supported JNDI properties: - * connectionfactory, queue, topic, destination. - * @param address of the connection or node to create. - */ - private Object createJMSProviderObject(String className, String address) { - /* Eventually maybe needed to be redefined */ - final String initialContext; - if (CoreClient.isQpidClient()) { - initialContext = QPID_INITIAL_CONTEXT; - } else { - initialContext = AMQ_INITIAL_CONTEXT; + + Destination getDestination() { + return destination; } - Properties properties = new Properties(); + + /** + * @param connectionFactory - often referred to as broker url + */ + void setConnectionFactory(String connectionFactory) { + this.connectionFactory = connectionFactory; + } + + /** + * @param queueOrTopic - destination can be either queue or topic + */ + void setDestinationName(String queueOrTopic) { + this.queueOrTopic = queueOrTopic; + } + + /** + * MessagingExceptionListener is created for each connection made. + */ + class MessagingExceptionListener implements ExceptionListener { + @Override + public void onException(JMSException e) { + LOG.error("ExceptionListener error detected! \n{}\n{}", e.getMessage(), e.getCause()); + e.printStackTrace(); + System.exit(1); + } + } + + /** + * Creates a destination for a specified name. + * + * @param destination for which destination is to be created. + * @return created Destination object + */ + Destination createDestination(String destination) { + return (Destination) createJMSProviderObject("destination", destination); + } + + /** + * Create queue object + * + * @param queueName name of the queue to be created + * @return created Queue object + */ + Queue createQueue(String queueName) { + return (Queue) createJMSProviderObject("queue", queueName); + } + + /** + * Create topic object + * + * @param topicName name of the topic to be created + * @return created Topic object + */ + Topic createTopic(String topicName) { + return (Topic) createJMSProviderObject("topic", topicName); + } + + /** + * Creates an object using qpid/amq initial context factory. + * + * @param className can be any of the qpid/amq supported JNDI properties: + * connectionfactory, queue, topic, destination. + * @param address of the connection or node to create. + */ + private Object createJMSProviderObject(String className, String address) { + /* Eventually maybe needed to be redefined */ + final String initialContext; + if (CoreClient.isQpidClient()) { + initialContext = QPID_INITIAL_CONTEXT; + } else { + initialContext = AMQ_INITIAL_CONTEXT; + } + Properties properties = new Properties(); /* Name of the object is the same as class of the object */ - String name = className; - properties.setProperty("java.naming.factory.initial", initialContext); - properties.setProperty(className + "." + name, address); - - Object jmsProviderObject = null; - try { - Context context = new InitialContext(properties); - jmsProviderObject = context.lookup(name); - context.close(); - } catch (NamingException e) { - e.printStackTrace(); + String name = className; + properties.setProperty("java.naming.factory.initial", initialContext); + properties.setProperty(className + "." + name, address); + + Object jmsProviderObject = null; + try { + Context context = new InitialContext(properties); + jmsProviderObject = context.lookup(name); + context.close(); + } catch (NamingException e) { + e.printStackTrace(); + } + return jmsProviderObject; } - return jmsProviderObject; - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorClient.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorClient.java index 982f48d2..46af23be 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorClient.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorClient.java @@ -36,126 +36,126 @@ */ public class ConnectorClient extends CoreClient { - private ConnectorOptions connectorOptions; - private static int connectionsOpened = 0; - private static List exceptions = new ArrayList<>(); - private static Logger LOG_CLEAN = LoggerFactory.getLogger(MessageFormatter.class); + private ConnectorOptions connectorOptions; + private static int connectionsOpened = 0; + private static List exceptions = new ArrayList<>(); + private static Logger LOG_CLEAN = LoggerFactory.getLogger(MessageFormatter.class); - ConnectorClient(String[] arguments) { - connectorOptions = new ConnectorOptions(); - ClientOptionManager.applyClientArguments(connectorOptions, arguments); - } - - - @Override - void startClient() { - // start all connections - createConnectionObjects(connectorOptions.getOption(ClientOptions.OBJ_CTRL).getDefaultValue()); - if (exceptions.isEmpty()) { - startConnections(); - } - int count = Integer.parseInt((this.getClientOptions().getOption(ClientOptions.COUNT).getValue())); - LOG_CLEAN.info(connectionsOpened + " " + exceptions.size() + " " + count); - for (Throwable t : exceptions) { - LOG.error(t.getMessage(), t.getCause()); + ConnectorClient(String[] arguments) { + connectorOptions = new ConnectorOptions(); + ClientOptionManager.applyClientArguments(connectorOptions, arguments); } - closeConnObjects(this, - Double.parseDouble(this.getClientOptions().getOption(ClientOptions.CLOSE_SLEEP).getValue())); - if (exceptions.size() > 0) { - System.exit(exceptions.size()); - } - } - /** - * Start connections created by ::createConnectionObject() - */ - private void startConnections() { - for (Connection connection : this.getConnections()) { - try { - connection.start(); - connectionsOpened++; - } catch (JMSException e) { - exceptions.add(new JmsMessagingException("Failed to start a connection.\n" + e.getMessage(), e.getCause())); - } - } - } - /** - * Create given number of Connection, Session, MessageProducer, - * MessageConsumer, TemporaryQueue objects. - * - * @param objCtrl specifies which objects are to be created - */ - private void createConnectionObjects(String objCtrl) { - if (connectorOptions.getOption(ClientOptions.ADDRESS).hasParsedValue()) { - objCtrl = "CESR"; - } else if (connectorOptions.getOption(ClientOptions.OBJ_CTRL).hasParsedValue()) { - objCtrl = connectorOptions.getOption(ClientOptions.OBJ_CTRL).getValue().toUpperCase(); + @Override + void startClient() { + // start all connections + createConnectionObjects(connectorOptions.getOption(ClientOptions.OBJ_CTRL).getDefaultValue()); + if (exceptions.isEmpty()) { + startConnections(); + } + int count = Integer.parseInt((this.getClientOptions().getOption(ClientOptions.COUNT).getValue())); + LOG_CLEAN.info(connectionsOpened + " " + exceptions.size() + " " + count); + for (Throwable t : exceptions) { + LOG.error(t.getMessage(), t.getCause()); + } + closeConnObjects(this, + Double.parseDouble(this.getClientOptions().getOption(ClientOptions.CLOSE_SLEEP).getValue())); + if (exceptions.size() > 0) { + System.exit(exceptions.size()); + } } - int count = Integer.parseInt(connectorOptions.getOption(ClientOptions.COUNT).getValue()); - try { - // create N Connections - for (int i = 0; i < count; i++) { - this.createConnection(connectorOptions); - } - // create N sEssions - if (objCtrl.contains("E")) { - for (Connection connection : getConnections()) { - createSession(connectorOptions, connection, false); + /** + * Start connections created by ::createConnectionObject() + */ + private void startConnections() { + for (Connection connection : this.getConnections()) { + try { + connection.start(); + connectionsOpened++; + } catch (JMSException e) { + exceptions.add(new JmsMessagingException("Failed to start a connection.\n" + e.getMessage(), e.getCause())); + } } + } - Destination destination = null; - if (objCtrl.contains("S") || objCtrl.contains("R")) { - destination = this.getDestination(); + /** + * Create given number of Connection, Session, MessageProducer, + * MessageConsumer, TemporaryQueue objects. + * + * @param objCtrl specifies which objects are to be created + */ + private void createConnectionObjects(String objCtrl) { + if (connectorOptions.getOption(ClientOptions.ADDRESS).hasParsedValue()) { + objCtrl = "CESR"; + } else if (connectorOptions.getOption(ClientOptions.OBJ_CTRL).hasParsedValue()) { + objCtrl = connectorOptions.getOption(ClientOptions.OBJ_CTRL).getValue().toUpperCase(); } - // create N Senders (MessageProducers) - if (objCtrl.contains("S")) { - for (Session session : getSessions()) { - MessageProducer producer = session.createProducer(destination); - addMessageProducer(producer); - } - // create N Receivers (MessageConsumers) - } - if (objCtrl.contains("R")) { - for (Session session : getSessions()) { - MessageConsumer consumer = session.createConsumer(destination); - addMessageConsumer(consumer); - } - } - // create temporary queue (the only queue we can create with JMSSession) - if (objCtrl.contains("Q")) { - int qCount = Integer.parseInt(connectorOptions.getOption(ClientOptions.Q_COUNT).getValue()); - if (qCount > count) { - qCount = count; - } - for (Session session : getSessions()) { - if (qCount > 0) { - Queue queue = session.createTemporaryQueue(); - addQueue(queue); - qCount--; - } else { - break; + int count = Integer.parseInt(connectorOptions.getOption(ClientOptions.COUNT).getValue()); + try { + // create N Connections + for (int i = 0; i < count; i++) { + this.createConnection(connectorOptions); } - } - } - } - if (LOG.isTraceEnabled()) { - int conns = (getConnections() == null) ? 0 : getConnections().size(); - int sesss = (getSessions() == null) ? 0 : getSessions().size(); - int sends = (getProducers() == null) ? 0 : getProducers().size(); - int reces = (getConsumers() == null) ? 0 : getConsumers().size(); - int queues = (getQueues() == null) ? 0: getQueues().size(); - LOG.trace("\tC={}\tE={}\tS={}\tR={}\tQ={}", conns, sesss, sends, reces, queues); - } - } catch (JMSException e) { - exceptions.add(new JmsMessagingException("Failed to create 'obj-ctrl.\n" + e.getMessage(), e.getCause())); + // create N sEssions + if (objCtrl.contains("E")) { + for (Connection connection : getConnections()) { + createSession(connectorOptions, connection, false); + } + + Destination destination = null; + if (objCtrl.contains("S") || objCtrl.contains("R")) { + destination = this.getDestination(); + } + // create N Senders (MessageProducers) + if (objCtrl.contains("S")) { + for (Session session : getSessions()) { + MessageProducer producer = session.createProducer(destination); + addMessageProducer(producer); + } + // create N Receivers (MessageConsumers) + } + if (objCtrl.contains("R")) { + for (Session session : getSessions()) { + MessageConsumer consumer = session.createConsumer(destination); + addMessageConsumer(consumer); + } + } + // create temporary queue (the only queue we can create with JMSSession) + if (objCtrl.contains("Q")) { + int qCount = Integer.parseInt(connectorOptions.getOption(ClientOptions.Q_COUNT).getValue()); + if (qCount > count) { + qCount = count; + } + for (Session session : getSessions()) { + if (qCount > 0) { + Queue queue = session.createTemporaryQueue(); + addQueue(queue); + qCount--; + } else { + break; + } + } + } + } + + if (LOG.isTraceEnabled()) { + int conns = (getConnections() == null) ? 0 : getConnections().size(); + int sesss = (getSessions() == null) ? 0 : getSessions().size(); + int sends = (getProducers() == null) ? 0 : getProducers().size(); + int reces = (getConsumers() == null) ? 0 : getConsumers().size(); + int queues = (getQueues() == null) ? 0 : getQueues().size(); + LOG.trace("\tC={}\tE={}\tS={}\tR={}\tQ={}", conns, sesss, sends, reces, queues); + } + } catch (JMSException e) { + exceptions.add(new JmsMessagingException("Failed to create 'obj-ctrl.\n" + e.getMessage(), e.getCause())); + } } - } - @Override - ClientOptions getClientOptions() { - return connectorOptions; - } + @Override + ClientOptions getClientOptions() { + return connectorOptions; + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorOptions.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorOptions.java index 86ac2342..3cc3f64f 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorOptions.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ConnectorOptions.java @@ -30,65 +30,65 @@ * Default options for ConnectorClient. */ public class ConnectorOptions extends ClientOptions { - private List options = new LinkedList(); - private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); - private final List connectorDefaultOptions = new LinkedList(); + private List options = new LinkedList(); + private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); + private final List connectorDefaultOptions = new LinkedList(); - { - connectorDefaultOptions.addAll(Arrays.asList( - new com.redhat.mqe.lib.Option(ADDRESS, "a", "CCADDRESS", "?", "If specified the C senders and receivers are created for this address"), - new com.redhat.mqe.lib.Option(OBJ_CTRL, "", "OBJCTRL", "C", "Optional creation object control (syntax C/E/S/R/Q stands for Connection, sEssion, Sender, Receiver, Queue)"), - new com.redhat.mqe.lib.Option(COUNT, "c", "CONNCOUNT", "1", "Specify how many connections will make"), - new com.redhat.mqe.lib.Option(Q_COUNT, "", "QCOUNT", "1", "Specify amount of queues created"), - // TODO JMS+SYNC_MODE? - new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SMODE", "action", "Optional action synchronization mode: none/session/action (JMS does not support none & session modes)") - )); - } + { + connectorDefaultOptions.addAll(Arrays.asList( + new com.redhat.mqe.lib.Option(ADDRESS, "a", "CCADDRESS", "?", "If specified the C senders and receivers are created for this address"), + new com.redhat.mqe.lib.Option(OBJ_CTRL, "", "OBJCTRL", "C", "Optional creation object control (syntax C/E/S/R/Q stands for Connection, sEssion, Sender, Receiver, Queue)"), + new com.redhat.mqe.lib.Option(COUNT, "c", "CONNCOUNT", "1", "Specify how many connections will make"), + new com.redhat.mqe.lib.Option(Q_COUNT, "", "QCOUNT", "1", "Specify amount of queues created"), + // TODO JMS+SYNC_MODE? + new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SMODE", "action", "Optional action synchronization mode: none/session/action (JMS does not support none & session modes)") + )); + } - ConnectorOptions() { - this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), connectorDefaultOptions); - } + ConnectorOptions() { + this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), connectorDefaultOptions); + } - @Override - public com.redhat.mqe.lib.Option getOption(String name) { - if (name != null) { - for (com.redhat.mqe.lib.Option option : options) { - if (name.equals(option.getName())) - return option; - } - } else { - LOG.error("Accessing client options map with null key."); - throw new IllegalArgumentException("Null name is not allowed!"); + @Override + public com.redhat.mqe.lib.Option getOption(String name) { + if (name != null) { + for (com.redhat.mqe.lib.Option option : options) { + if (name.equals(option.getName())) + return option; + } + } else { + LOG.error("Accessing client options map with null key."); + throw new IllegalArgumentException("Null name is not allowed!"); + } + return null; } - return null; - } - @Override - public List getClientDefaultOptions() { - return connectorDefaultOptions; - } + @Override + public List getClientDefaultOptions() { + return connectorDefaultOptions; + } - @Override - public List getClientOptions() { - return options; - } + @Override + public List getClientOptions() { + return options; + } - @Override - public String toString() { - return "ConnectorOptions{" + - "options=" + options + - '}'; - } - /** - -h, --help show this help message and exit - -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) - --duration DURATION Opened objects will be held until duration passes by, Also the sessions if exists will be synced every T=1s (default 0) - -a CCADDRESS, --address CCADDRESS If specified the C senders and receivers are created for this address (default ) - --obj-ctrl OBJCTRL Optional creation object control (syntax C/E/S/R stands for Connection, sEssion, Sender, Receiver) (default C) - --sync-mode SMODE Optional action synchronization mode: none/session/action (JMS does not support none & session modes) (default action) - -c CONN_CNT, --conn-cnt CONN_CNT Specify how many connections will make (default 1) - --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all - --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI - --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) - */ + @Override + public String toString() { + return "ConnectorOptions{" + + "options=" + options + + '}'; + } + /** + -h, --help show this help message and exit + -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) + --duration DURATION Opened objects will be held until duration passes by, Also the sessions if exists will be synced every T=1s (default 0) + -a CCADDRESS, --address CCADDRESS If specified the C senders and receivers are created for this address (default ) + --obj-ctrl OBJCTRL Optional creation object control (syntax C/E/S/R stands for Connection, sEssion, Sender, Receiver) (default C) + --sync-mode SMODE Optional action synchronization mode: none/session/action (JMS does not support none & session modes) (default action) + -c CONN_CNT, --conn-cnt CONN_CNT Specify how many connections will make (default 1) + --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all + --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI + --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) + */ } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/CoreClient.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/CoreClient.java index a3d10ae3..aba6b99c 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/CoreClient.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/CoreClient.java @@ -36,551 +36,552 @@ * Core implementation of creating various connections to brokers using clients. */ public abstract class CoreClient { - static final String AMQ_CLIENT_TYPE = "amq"; - static final String QPID_CLIENT_TYPE = "qpid"; - static Logger LOG = LoggerFactory.getLogger(CoreClient.class); - private ConnectionManager connectionManager; - static Map connectionOptionsUrlMap; - private static final Map SESSION_ACK_MAP = new HashMap<>(5); - private static final Map CONNECTION_TRANSLATION_MAP = new HashMap<>(); - - static { + static final String AMQ_CLIENT_TYPE = "amq"; + static final String QPID_CLIENT_TYPE = "qpid"; + static Logger LOG = LoggerFactory.getLogger(CoreClient.class); + private ConnectionManager connectionManager; + static Map connectionOptionsUrlMap; + private static final Map SESSION_ACK_MAP = new HashMap<>(5); + private static final Map CONNECTION_TRANSLATION_MAP = new HashMap<>(); + + static { // SESSION_ACK_MAP.put("transacted", Session.SESSION_TRANSACTED); // This is handled by TRANSACTED option - SESSION_ACK_MAP.put("auto", Session.AUTO_ACKNOWLEDGE); - SESSION_ACK_MAP.put("client", Session.CLIENT_ACKNOWLEDGE); - SESSION_ACK_MAP.put("dups_ok", Session.DUPS_OK_ACKNOWLEDGE); + SESSION_ACK_MAP.put("auto", Session.AUTO_ACKNOWLEDGE); + SESSION_ACK_MAP.put("client", Session.CLIENT_ACKNOWLEDGE); + SESSION_ACK_MAP.put("dups_ok", Session.DUPS_OK_ACKNOWLEDGE); // SESSION_ACK_MAP.put("individual", Session.INDIVIDUAL_ACKNOWLEDGE); // ActiveMQSpecific? - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_HEARTBEAT, "amqp.idleTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.USERNAME, "jms.username"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.PASSWORD, "jms.password"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_VHOST, "amqp.vhost"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_MECHS, "amqp.saslMechanisms"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_LAYER, "amqp.saslLayer"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_MAX_FRAME_SIZE, "amqp.maxFrameSize"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_DRAIN_TIMEOUT, "amqp.drainTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLIENTID, "jms.clientID"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_ASYNC_SEND, "jms.forceAsyncSend"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SYNC_SEND, "jms.alwaysSyncSend"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_ASYNC_ACKS, "jms.sendAcksAsync"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_LOC_MSG_PRIO, "jms.localMessagePriority"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_VALID_PROP_NAMES, "jms.validatePropertyNames"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECV_LOCAL_ONLY, "jms.receiveLocalOnly"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECV_NOWAIT_LOCAL, "jms.receiveNoWaitLocalOnly"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_QUEUE_PREFIX, "jms.queuePrefix"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TOPIC_PREFIX, "jms.topicPrefix"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLOSE_TIMEOUT, "jms.closeTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CONN_TIMEOUT, "jms.connectTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLIENTID_PREFIX, "jms.clientIDPrefix"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CONNID_PREFIX, "jms.connectionIDPrefix"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_POPULATE_JMSXUSERID, "jms.populateJMSXUserID"); - - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_QUEUE, "jms.prefetchPolicy.queuePrefetch"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_TOPIC, "jms.prefetchPolicy.topicPrefetch"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_BROWSER, "jms.prefetchPolicy.queueBrowserPrefetch"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_DUR_TOPIC, "jms.prefetchPolicy.durableTopicPrefetch"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_ALL, "jms.prefetchPolicy.all"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_MAX_REDELIVERIES, "jms.redeliveryPolicy.maxRedeliveries"); - - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RETRIES, "failover.maxReconnectAttempts"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_TIMEOUT, "failover.reconnectDelay"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_INTERVAL, "failover.maxReconnectDelay"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_BACKOFF, "failover.useReconnectBackOff"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_BACKOFF_MULTIPLIER, "failover.reconnectBackOffMultiplier"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_START_LIMIT, "failover.startupMaxReconnectAttempts"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_INITIAL_DELAY, "failover.initialReconnectDelay"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_WARN_ATTEMPTS, "failover.warnAfterReconnectAttempts"); - - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYSTORE_LOC, "transport.keyStoreLocation"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYSTORE_PASS, "transport.keyStorePassword"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUSTSTORE_LOC, "transport.trustStoreLocation"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUSTSTORE_PASS, "transport.trustStorePassword"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_STORE_TYPE, "transport.storeType"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_CONTEXT_PROTOCOL, "transport.contextProtocol"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_ENA_CIPHERED, "transport.enabledCipherSuites"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_DIS_CIPHERED, "transport.disabledCipherSuites"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_ENA_PROTOS, "transport.enabledProtocols"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_DIS_PROTOS, "transport.disabledProtocols"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUST_ALL, "transport.trustAll"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_VERIFY_HOST, "transport.verifyHost"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYALIAS, "transport.keyAlias"); - - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SEND_BUF_SIZE, "transport.sendBufferSize"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_RECV_BUF_SIZE, "transport.receiveBufferSize"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_TRAFFIC_CLASS, "transport.trafficClass"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_CON_TIMEOUT, "transport.connectTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SOCK_TIMEOUT, "transport.soTimeout"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SOCK_LINGER, "transport.soLinger"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_KEEP_ALIVE, "transport.tcpKeepAlive"); - CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_NO_DELAY, "transport.tcpNoDelay"); - } - - private List connections; - private List sessions; - private List messageProducers; - private List messageConsumers; - private List queues; - private static String clientType; - - /** - * Method starts the given client. Serves as entry point. - */ - abstract void startClient(); - - /** - * Create @Connection for given client from provided client options. - * By default, we prefer to use brokerUrl to not set up anything. - * Also, no brokerUrl can be provided, but we need all the other connection - * options to create @Connection. - * - * @param clientOptions options of given client - * @return newly created Connection from provided client options - */ - public Connection createConnection(ClientOptions clientOptions) { + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_HEARTBEAT, "amqp.idleTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.USERNAME, "jms.username"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.PASSWORD, "jms.password"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_VHOST, "amqp.vhost"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_MECHS, "amqp.saslMechanisms"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SASL_LAYER, "amqp.saslLayer"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_MAX_FRAME_SIZE, "amqp.maxFrameSize"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_DRAIN_TIMEOUT, "amqp.drainTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLIENTID, "jms.clientID"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_ASYNC_SEND, "jms.forceAsyncSend"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SYNC_SEND, "jms.alwaysSyncSend"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_ASYNC_ACKS, "jms.sendAcksAsync"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_LOC_MSG_PRIO, "jms.localMessagePriority"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_VALID_PROP_NAMES, "jms.validatePropertyNames"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECV_LOCAL_ONLY, "jms.receiveLocalOnly"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECV_NOWAIT_LOCAL, "jms.receiveNoWaitLocalOnly"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_QUEUE_PREFIX, "jms.queuePrefix"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TOPIC_PREFIX, "jms.topicPrefix"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLOSE_TIMEOUT, "jms.closeTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CONN_TIMEOUT, "jms.connectTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CLIENTID_PREFIX, "jms.clientIDPrefix"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_CONNID_PREFIX, "jms.connectionIDPrefix"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_POPULATE_JMSXUSERID, "jms.populateJMSXUserID"); + + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_QUEUE, "jms.prefetchPolicy.queuePrefetch"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_TOPIC, "jms.prefetchPolicy.topicPrefetch"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_BROWSER, "jms.prefetchPolicy.queueBrowserPrefetch"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_DUR_TOPIC, "jms.prefetchPolicy.durableTopicPrefetch"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_PREFETCH_ALL, "jms.prefetchPolicy.all"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_MAX_REDELIVERIES, "jms.redeliveryPolicy.maxRedeliveries"); + + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RETRIES, "failover.maxReconnectAttempts"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_TIMEOUT, "failover.reconnectDelay"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_INTERVAL, "failover.maxReconnectDelay"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_BACKOFF, "failover.useReconnectBackOff"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_BACKOFF_MULTIPLIER, "failover.reconnectBackOffMultiplier"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_START_LIMIT, "failover.startupMaxReconnectAttempts"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_INITIAL_DELAY, "failover.initialReconnectDelay"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_RECONNECT_WARN_ATTEMPTS, "failover.warnAfterReconnectAttempts"); + + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYSTORE_LOC, "transport.keyStoreLocation"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYSTORE_PASS, "transport.keyStorePassword"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUSTSTORE_LOC, "transport.trustStoreLocation"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUSTSTORE_PASS, "transport.trustStorePassword"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_STORE_TYPE, "transport.storeType"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_CONTEXT_PROTOCOL, "transport.contextProtocol"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_ENA_CIPHERED, "transport.enabledCipherSuites"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_DIS_CIPHERED, "transport.disabledCipherSuites"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_ENA_PROTOS, "transport.enabledProtocols"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_DIS_PROTOS, "transport.disabledProtocols"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_TRUST_ALL, "transport.trustAll"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_VERIFY_HOST, "transport.verifyHost"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_SSL_KEYALIAS, "transport.keyAlias"); + + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SEND_BUF_SIZE, "transport.sendBufferSize"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_RECV_BUF_SIZE, "transport.receiveBufferSize"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_TRAFFIC_CLASS, "transport.trafficClass"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_CON_TIMEOUT, "transport.connectTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SOCK_TIMEOUT, "transport.soTimeout"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_SOCK_LINGER, "transport.soLinger"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_KEEP_ALIVE, "transport.tcpKeepAlive"); + CONNECTION_TRANSLATION_MAP.put(ClientOptions.CON_TCP_NO_DELAY, "transport.tcpNoDelay"); + } + + private List connections; + private List sessions; + private List messageProducers; + private List messageConsumers; + private List queues; + private static String clientType; + + /** + * Method starts the given client. Serves as entry point. + */ + abstract void startClient(); + + /** + * Create @Connection for given client from provided client options. + * By default, we prefer to use brokerUrl to not set up anything. + * Also, no brokerUrl can be provided, but we need all the other connection + * options to create @Connection. + * + * @param clientOptions options of given client + * @return newly created Connection from provided client options + */ + public Connection createConnection(ClientOptions clientOptions) { // Map updatedOptions = clientOptions.getUpdatedOptions(); - String brokerUrl; - if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue()) { - // Use the whole provided broker-url string with options - brokerUrl = clientOptions.getOption(ClientOptions.BROKER_URI).getValue(); - } else { - // Use only protocol,credentials,host and port - brokerUrl = clientOptions.getOption(ClientOptions.BROKER).getValue(); - if (clientOptions.getOption(ClientOptions.BROKER_OPTIONS).hasParsedValue()) { - brokerUrl += "?" + clientOptions.getOption(ClientOptions.BROKER_OPTIONS).getValue(); - } + String brokerUrl; + if (clientOptions.getOption(ClientOptions.BROKER_URI).hasParsedValue()) { + // Use the whole provided broker-url string with options + brokerUrl = clientOptions.getOption(ClientOptions.BROKER_URI).getValue(); + } else { + // Use only protocol,credentials,host and port + brokerUrl = clientOptions.getOption(ClientOptions.BROKER).getValue(); + if (clientOptions.getOption(ClientOptions.BROKER_OPTIONS).hasParsedValue()) { + brokerUrl += "?" + clientOptions.getOption(ClientOptions.BROKER_OPTIONS).getValue(); + } + } + connectionManager = new ConnectionManager(clientOptions, brokerUrl); + Connection connection = connectionManager.getConnection(); + addConnection(connection); + return connection; } - connectionManager = new ConnectionManager(clientOptions, brokerUrl); - Connection connection = connectionManager.getConnection(); - addConnection(connection); - return connection; - } - - /** - * Abstract method, returns the current client Options. - * - * @return the given ClientOption list - */ - abstract ClientOptions getClientOptions(); - - /** - * Create session for client on provided connection using clientOptions - * - * @param clientOptions options of the client - * @param connection to be created session on - * @param transacted defines whether create transacted session or not - * @return created session object - */ - Session createSession(ClientOptions clientOptions, Connection connection, boolean transacted) { - Session session = null; + + /** + * Abstract method, returns the current client Options. + * + * @return the given ClientOption list + */ + abstract ClientOptions getClientOptions(); + + /** + * Create session for client on provided connection using clientOptions + * + * @param clientOptions options of the client + * @param connection to be created session on + * @param transacted defines whether create transacted session or not + * @return created session object + */ + Session createSession(ClientOptions clientOptions, Connection connection, boolean transacted) { + Session session = null; // boolean transacted = Boolean.parseBoolean(clientOptions.getOption(ClientOptions.TRANSACTED).getValue()); - int acknowledgeMode = SESSION_ACK_MAP.get(clientOptions.getOption(ClientOptions.SSN_ACK_MODE).getValue()); - try { - // if transacted is true, acknowledgeMode is ignored - session = connection.createSession(transacted, acknowledgeMode); - } catch (JMSException e) { - LOG.error("Error while creating session! " + e.getMessage()); - e.printStackTrace(); - System.exit(1); + int acknowledgeMode = SESSION_ACK_MAP.get(clientOptions.getOption(ClientOptions.SSN_ACK_MODE).getValue()); + try { + // if transacted is true, acknowledgeMode is ignored + session = connection.createSession(transacted, acknowledgeMode); + } catch (JMSException e) { + LOG.error("Error while creating session! " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + if (sessions == null) { + sessions = new ArrayList<>(); + } + sessions.add(session); + return session; } - if (sessions == null) { - sessions = new ArrayList<>(); + + Destination getDestination() { + return this.connectionManager.getDestination(); } - sessions.add(session); - return session; - } - - Destination getDestination() { - return this.connectionManager.getDestination(); - } - - String getDestinationType() { - return getClientOptions().getOption(ClientOptions.DESTINATION_TYPE).getValue(); - } - - /** - * Returns the list of connections for this client - * - * @return list of Connections - */ - List getConnections() { - return connections; - } - - /** - * After creation of new connection, this connection - * is automatically added to the list of connections. - * No need to use it explicitly. - * - * @param connection to be added to the list - */ - void addConnection(Connection connection) { - if (connections == null) { - connections = new ArrayList<>(getCount()); + + String getDestinationType() { + return getClientOptions().getOption(ClientOptions.DESTINATION_TYPE).getValue(); } - connections.add(connection); - } - - /** - * Returns the list of sessions for this client - * - * @return list of Sessions - */ - List getSessions() { - return sessions; - } - - /** - * Add this session to the list of sessions. - * - * @param session to be added to session list - */ - void addSession(Session session) { - if (sessions == null) { - sessions = new ArrayList<>(getCount()); + + /** + * Returns the list of connections for this client + * + * @return list of Connections + */ + List getConnections() { + return connections; } - sessions.add(session); - } - - /** - * Returns the list of MessageProducers for this client - * - * @return list of MessageProducers - */ - List getProducers() { - return messageProducers; - } - - /** - * Add this producer to the list of messageProducers. - * - * @param messageProducer to be added to messageProducers list - */ - void addMessageProducer(MessageProducer messageProducer) { - if (messageProducers == null) { - messageProducers = new ArrayList<>(getCount()); + + /** + * After creation of new connection, this connection + * is automatically added to the list of connections. + * No need to use it explicitly. + * + * @param connection to be added to the list + */ + void addConnection(Connection connection) { + if (connections == null) { + connections = new ArrayList<>(getCount()); + } + connections.add(connection); } - messageProducers.add(messageProducer); - } - - /** - * Returns the list of MessageConsumers for this client - * - * @return list of MessageConsumers - */ - List getConsumers() { - return messageConsumers; - } - - /** - * Add this consumer to the list of messageConsumer. - * - * @param messageConsumer to be added to messageConsumers list - */ - void addMessageConsumer(MessageConsumer messageConsumer) { - if (messageConsumers == null) { - messageConsumers = new ArrayList<>(getCount()); + + /** + * Returns the list of sessions for this client + * + * @return list of Sessions + */ + List getSessions() { + return sessions; } - messageConsumers.add(messageConsumer); - } - - /** - * Add given queue to queues list - * - * @param queue to be added to queues list - */ - void addQueue(Queue queue) { - if (queues == null) { - queues = new ArrayList<>(getCount()); + + /** + * Add this session to the list of sessions. + * + * @param session to be added to session list + */ + void addSession(Session session) { + if (sessions == null) { + sessions = new ArrayList<>(getCount()); + } + sessions.add(session); } - queues.add(queue); - } - - /** - * Returns the list of queues added - * - * @return queues added - */ - public List getQueues() { - return queues; - } - - /** - * Returns the number of "count" argument. - * - * @return number of messages/connections depending on client - */ - int getCount() { - return Integer.parseInt(getClientOptions().getOption(ClientOptions.COUNT).getValue()); - } - - /** - * Close objects for given Client. - * Sleep for given period of time before closing MessageProducer/Consumer, - * Session and Connection. - * - * @param client holding all the open connection objects - * @param closeSleep sleep for given period of time between closings objects - */ - static void closeConnObjects(CoreClient client, double closeSleep) { - long sleepMs = Math.round(closeSleep * 1000); - if (client.getProducers() != null) { - if (closeSleep > 0) { - LOG.debug("Sleeping before closing producers for " + closeSleep + " seconds."); - Utils.sleep(sleepMs); - } - for (MessageProducer producer : client.getProducers()) { - client.close(producer); - } + + /** + * Returns the list of MessageProducers for this client + * + * @return list of MessageProducers + */ + List getProducers() { + return messageProducers; } - if (client.getConsumers() != null) { - if (closeSleep > 0) { - LOG.debug("Sleeping before closing consumers for " + closeSleep + " seconds."); - Utils.sleep(sleepMs); - } - for (MessageConsumer consumer : client.getConsumers()) { - client.close(consumer); - } + /** + * Add this producer to the list of messageProducers. + * + * @param messageProducer to be added to messageProducers list + */ + void addMessageProducer(MessageProducer messageProducer) { + if (messageProducers == null) { + messageProducers = new ArrayList<>(getCount()); + } + messageProducers.add(messageProducer); + } + + /** + * Returns the list of MessageConsumers for this client + * + * @return list of MessageConsumers + */ + List getConsumers() { + return messageConsumers; + } + + /** + * Add this consumer to the list of messageConsumer. + * + * @param messageConsumer to be added to messageConsumers list + */ + void addMessageConsumer(MessageConsumer messageConsumer) { + if (messageConsumers == null) { + messageConsumers = new ArrayList<>(getCount()); + } + messageConsumers.add(messageConsumer); + } + + /** + * Add given queue to queues list + * + * @param queue to be added to queues list + */ + void addQueue(Queue queue) { + if (queues == null) { + queues = new ArrayList<>(getCount()); + } + queues.add(queue); + } + + /** + * Returns the list of queues added + * + * @return queues added + */ + public List getQueues() { + return queues; } - if (client.getSessions() != null) { - if (closeSleep > 0) { - LOG.debug("Sleeping before closing sessions for " + closeSleep + " seconds."); - Utils.sleep(sleepMs); - } - for (Session session : client.getSessions()) { - client.close(session); - } + /** + * Returns the number of "count" argument. + * + * @return number of messages/connections depending on client + */ + int getCount() { + return Integer.parseInt(getClientOptions().getOption(ClientOptions.COUNT).getValue()); } - if (closeSleep > 0) { - LOG.debug("Sleeping before closing connections for " + closeSleep + " seconds."); - Utils.sleep(sleepMs); + /** + * Close objects for given Client. + * Sleep for given period of time before closing MessageProducer/Consumer, + * Session and Connection. + * + * @param client holding all the open connection objects + * @param closeSleep sleep for given period of time between closings objects + */ + static void closeConnObjects(CoreClient client, double closeSleep) { + long sleepMs = Math.round(closeSleep * 1000); + if (client.getProducers() != null) { + if (closeSleep > 0) { + LOG.debug("Sleeping before closing producers for " + closeSleep + " seconds."); + Utils.sleep(sleepMs); + } + for (MessageProducer producer : client.getProducers()) { + client.close(producer); + } + } + + if (client.getConsumers() != null) { + if (closeSleep > 0) { + LOG.debug("Sleeping before closing consumers for " + closeSleep + " seconds."); + Utils.sleep(sleepMs); + } + for (MessageConsumer consumer : client.getConsumers()) { + client.close(consumer); + } + } + + if (client.getSessions() != null) { + if (closeSleep > 0) { + LOG.debug("Sleeping before closing sessions for " + closeSleep + " seconds."); + Utils.sleep(sleepMs); + } + for (Session session : client.getSessions()) { + client.close(session); + } + } + + if (closeSleep > 0) { + LOG.debug("Sleeping before closing connections for " + closeSleep + " seconds."); + Utils.sleep(sleepMs); + } + for (Connection connection : client.getConnections()) { + client.close(connection); + } } - for (Connection connection : client.getConnections()) { - client.close(connection); + + void close(Connection connection) { + try { + LOG.trace("Closing connection " + connection.toString()); + connection.close(); + } catch (JMSException e) { + e.printStackTrace(); + } } - } - - void close(Connection connection) { - try { - LOG.trace("Closing connection " + connection.toString()); - connection.close(); - } catch (JMSException e) { - e.printStackTrace(); + + void close(Session session) { + try { + LOG.trace("Closing session " + session.toString()); + session.close(); + } catch (JMSException e) { + e.printStackTrace(); + } } - } - - void close(Session session) { - try { - LOG.trace("Closing session " + session.toString()); - session.close(); - } catch (JMSException e) { - e.printStackTrace(); + + void close(MessageProducer messageProducer) { + try { + LOG.trace("Closing sender " + messageProducer.toString()); + messageProducer.close(); + } catch (JMSException e) { + e.printStackTrace(); + } } - } - - void close(MessageProducer messageProducer) { - try { - LOG.trace("Closing sender " + messageProducer.toString()); - messageProducer.close(); - } catch (JMSException e) { - e.printStackTrace(); + + void close(MessageConsumer messageConsumer) { + try { + LOG.trace("Closing receiver " + messageConsumer.toString()); + messageConsumer.close(); + } catch (JMSException e) { + e.printStackTrace(); + } } - } - - void close(MessageConsumer messageConsumer) { - try { - LOG.trace("Closing receiver " + messageConsumer.toString()); - messageConsumer.close(); - } catch (JMSException e) { - e.printStackTrace(); + + /** + * Print message using MessageFormatter in given format. + * Printing format is specified using LOG_MSGS value + * as (dict|body|upstream|none). + * + * @param clientOptions options of the client + * @param message to be printed + */ + static void printMessage(ClientOptions clientOptions, Message message) { + MessageFormatter formatter = new AMQPMessageFormatter(); + switch (clientOptions.getOption(ClientOptions.LOG_MSGS).getValue()) { + case "dict": + formatter.printMessageAsDict(message); + break; + case "body": + formatter.printMessageBodyAsText(message); + break; + case "interop": + formatter.printMessageAsInterop(message); + break; + case "none": + default: + break; + } } - } - - /** - * Print message using MessageFormatter in given format. - * Printing format is specified using LOG_MSGS value - * as (dict|body|upstream|none). - * - * @param clientOptions options of the client - * @param message to be printed - */ - static void printMessage(ClientOptions clientOptions, Message message) { - MessageFormatter formatter = new AMQPMessageFormatter(); - switch (clientOptions.getOption(ClientOptions.LOG_MSGS).getValue()) { - case "dict": - formatter.printMessageAsDict(message); - break; - case "body": - formatter.printMessageBodyAsText(message); - break; - case "interop": - formatter.printMessageAsInterop(message); - break; - case "none": - default: - break; + + // TODO - make it better, easily extensible for future clients + static boolean isAMQClient() { + return clientType.equals(AMQ_CLIENT_TYPE); } - } - - // TODO - make it better, easily extensible for future clients - static boolean isAMQClient() { - return clientType.equals(AMQ_CLIENT_TYPE); - } - - static boolean isQpidClient() { - return clientType.equals(QPID_CLIENT_TYPE); - } - - /** - * Supported client types are 'qpid' and 'amq'. - * Specific broker-related data types are different among different - * brokers. - * - * @param client to which broker will connect. Supported amq/qpid values. - */ - public static void setClientType(String client) { - clientType = client.toLowerCase(); - } - - /** - * Do the given transaction. - * - * @param session to do transaction on this session - * @param transaction transaction action type to perform - */ - static void doTransaction(Session session, String transaction) { - try { - StringBuilder txLog = new StringBuilder("Performed "); - switch (transaction.toLowerCase()) { - case "commit": - session.commit(); - txLog.append("Commit"); - break; - case "rollback": - session.rollback(); - txLog.append("Rollback"); - break; - case "recover": - session.recover(); - txLog.append("Recover"); - break; - case "none": - txLog.append("None"); - break; - default: - LOG.error("Unknown tx action: '" + transaction + "'! Exiting"); - System.exit(2); - } - LOG.trace(txLog.append(" TX action").toString()); - } catch (JMSException e) { - e.printStackTrace(); + + static boolean isQpidClient() { + return clientType.equals(QPID_CLIENT_TYPE); } - } - - /** - * Set global options applicable to all clients. - * Only Logging for now. - * - * @param clientOptions options of the client - */ - static void setGlobalClientOptions(ClientOptions clientOptions) { - if (clientOptions.getOption(ClientOptions.LOG_LEVEL).hasParsedValue()) { - Utils.setLogLevel(clientOptions.getOption(ClientOptions.LOG_LEVEL).getValue()); + + /** + * Supported client types are 'qpid' and 'amq'. + * Specific broker-related data types are different among different + * brokers. + * + * @param client to which broker will connect. Supported amq/qpid values. + */ + public static void setClientType(String client) { + clientType = client.toLowerCase(); } - } - - /** - * Format broker connection strictly for 'broker' argument. - * Url consists of protocol, (username+password), hostname and port. - * - * @param clientOptions - * @return - */ - static String formBrokerUrl(ClientOptions clientOptions) { - StringBuilder brkCon = new StringBuilder(); - brkCon.append(clientOptions.getOption(ClientOptions.PROTOCOL).getValue()); - if (clientOptions.getOption(ClientOptions.FAILOVER_URL).hasParsedValue()) { - brkCon.append(":(").append(clientOptions.getOption(ClientOptions.FAILOVER_URL).getValue()).append(")"); - } else { - brkCon.append("://"); - if (isQpidClient()) { - if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue()) { - brkCon.append(clientOptions.getOption(ClientOptions.USERNAME).getValue()).append(":"); + + /** + * Do the given transaction. + * + * @param session to do transaction on this session + * @param transaction transaction action type to perform + */ + static void doTransaction(Session session, String transaction) { + try { + StringBuilder txLog = new StringBuilder("Performed "); + switch (transaction.toLowerCase()) { + case "commit": + session.commit(); + txLog.append("Commit"); + break; + case "rollback": + session.rollback(); + txLog.append("Rollback"); + break; + case "recover": + session.recover(); + txLog.append("Recover"); + break; + case "none": + txLog.append("None"); + break; + default: + LOG.error("Unknown tx action: '" + transaction + "'! Exiting"); + System.exit(2); + } + LOG.trace(txLog.append(" TX action").toString()); + } catch (JMSException e) { + e.printStackTrace(); } - if (clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { - brkCon.append(clientOptions.getOption(ClientOptions.PASSWORD).getValue()); + } + + /** + * Set global options applicable to all clients. + * Only Logging for now. + * + * @param clientOptions options of the client + */ + static void setGlobalClientOptions(ClientOptions clientOptions) { + if (clientOptions.getOption(ClientOptions.LOG_LEVEL).hasParsedValue()) { + Utils.setLogLevel(clientOptions.getOption(ClientOptions.LOG_LEVEL).getValue()); } - if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue() - || clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { - brkCon.append("@"); + } + + /** + * Format broker connection strictly for 'broker' argument. + * Url consists of protocol, (username+password), hostname and port. + * + * @param clientOptions + * @return + */ + static String formBrokerUrl(ClientOptions clientOptions) { + StringBuilder brkCon = new StringBuilder(); + brkCon.append(clientOptions.getOption(ClientOptions.PROTOCOL).getValue()); + if (clientOptions.getOption(ClientOptions.FAILOVER_URL).hasParsedValue()) { + brkCon.append(":(").append(clientOptions.getOption(ClientOptions.FAILOVER_URL).getValue()).append(")"); + } else { + brkCon.append("://"); + if (isQpidClient()) { + if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue()) { + brkCon.append(clientOptions.getOption(ClientOptions.USERNAME).getValue()).append(":"); + } + if (clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { + brkCon.append(clientOptions.getOption(ClientOptions.PASSWORD).getValue()); + } + if (clientOptions.getOption(ClientOptions.USERNAME).hasParsedValue() + || clientOptions.getOption(ClientOptions.PASSWORD).hasParsedValue()) { + brkCon.append("@"); + } + } + brkCon.append(clientOptions.getOption(ClientOptions.BROKER_HOST).getValue()).append(":") + .append(clientOptions.getOption(ClientOptions.BROKER_PORT).getValue()); } - } - brkCon.append(clientOptions.getOption(ClientOptions.BROKER_HOST).getValue()).append(":") - .append(clientOptions.getOption(ClientOptions.BROKER_PORT).getValue()); + LOG.trace("BrokerUrl=" + brkCon.toString()); + return brkCon.toString(); } - LOG.trace("BrokerUrl=" + brkCon.toString()); - return brkCon.toString(); - } - - /** - * Create connection url from given options. - * - * @return string of options starting as "?" - */ - static String getConnectionOptionsAsUrl() { - StringBuilder conOptUrl = new StringBuilder(); - if (connectionOptionsUrlMap != null) { - for (String optionName : connectionOptionsUrlMap.keySet()) { - String divider = (conOptUrl.length() == 0) ? "?" : "&"; - conOptUrl.append(divider); - conOptUrl.append(optionName).append("="); - appendSingleQuote(conOptUrl).append(connectionOptionsUrlMap.get(optionName)); - appendSingleQuote(conOptUrl); - } - return conOptUrl.toString(); - } else { - return ""; + + /** + * Create connection url from given options. + * + * @return string of options starting as "?" + */ + static String getConnectionOptionsAsUrl() { + StringBuilder conOptUrl = new StringBuilder(); + if (connectionOptionsUrlMap != null) { + for (String optionName : connectionOptionsUrlMap.keySet()) { + String divider = (conOptUrl.length() == 0) ? "?" : "&"; + conOptUrl.append(divider); + conOptUrl.append(optionName).append("="); + appendSingleQuote(conOptUrl).append(connectionOptionsUrlMap.get(optionName)); + appendSingleQuote(conOptUrl); + } + return conOptUrl.toString(); + } else { + return ""; + } } - } - - /** - * Do not use quotes in connection options for Qpid JMS AMQP client, - * codename (AMQ client). - * @param stringBuilder string to have appended the singleQuote - * @return same string with the appended quote - */ - static StringBuilder appendSingleQuote(StringBuilder stringBuilder) { - return (isAMQClient()) ? stringBuilder : stringBuilder.append("'"); - } - - /** - * Fill connectionOptionsUrlMap with the data. - * If needed convert the client input connectin option - * to the appropriate jms connection option. - * Also, if needed, change seconds to milliseconds. - */ - static void addConnectionOptions(com.redhat.mqe.lib.Option option) { - if (connectionOptionsUrlMap == null) { - connectionOptionsUrlMap = new HashMap<>(); + + /** + * Do not use quotes in connection options for Qpid JMS AMQP client, + * codename (AMQ client). + * + * @param stringBuilder string to have appended the singleQuote + * @return same string with the appended quote + */ + static StringBuilder appendSingleQuote(StringBuilder stringBuilder) { + return (isAMQClient()) ? stringBuilder : stringBuilder.append("'"); } - String jmsConOptionName = CONNECTION_TRANSLATION_MAP.get(option.getName()); - if (jmsConOptionName != null) { - // TODO need of conversion map, if more options are neeed to be altered - if (option.getName().equals(ClientOptions.CON_HEARTBEAT)) { - Integer value = Math.round(Float.parseFloat(option.getValue()) * 1000); - connectionOptionsUrlMap.put(jmsConOptionName, value.toString()); - } else { - connectionOptionsUrlMap.put(jmsConOptionName, option.getValue()); - } - } else { - if (option.getName().equals(ClientOptions.CON_RECONNECT)) { - // use failover mechanism, conn-reconnect does not perform nor add any other action to the client - return; - } - LOG.error("Connection option {} is not recognized! ", option.getName()); - System.exit(2); + + /** + * Fill connectionOptionsUrlMap with the data. + * If needed convert the client input connectin option + * to the appropriate jms connection option. + * Also, if needed, change seconds to milliseconds. + */ + static void addConnectionOptions(com.redhat.mqe.lib.Option option) { + if (connectionOptionsUrlMap == null) { + connectionOptionsUrlMap = new HashMap<>(); + } + String jmsConOptionName = CONNECTION_TRANSLATION_MAP.get(option.getName()); + if (jmsConOptionName != null) { + // TODO need of conversion map, if more options are neeed to be altered + if (option.getName().equals(ClientOptions.CON_HEARTBEAT)) { + Integer value = Math.round(Float.parseFloat(option.getValue()) * 1000); + connectionOptionsUrlMap.put(jmsConOptionName, value.toString()); + } else { + connectionOptionsUrlMap.put(jmsConOptionName, option.getValue()); + } + } else { + if (option.getName().equals(ClientOptions.CON_RECONNECT)) { + // use failover mechanism, conn-reconnect does not perform nor add any other action to the client + return; + } + LOG.error("Connection option {} is not recognized! ", option.getName()); + System.exit(2); + } } - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageBrowser.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageBrowser.java index 0f190106..a67b01a0 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageBrowser.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageBrowser.java @@ -35,58 +35,58 @@ */ public class MessageBrowser extends CoreClient { - private boolean transacted; - private String msgSelector; - ClientOptions clientOptions; + private boolean transacted; + private String msgSelector; + ClientOptions clientOptions; - MessageBrowser(ClientOptions clientOptions) { - this.clientOptions = clientOptions; - } + MessageBrowser(ClientOptions clientOptions) { + this.clientOptions = clientOptions; + } - @Override - ClientOptions getClientOptions() { - return this.clientOptions; - } + @Override + ClientOptions getClientOptions() { + return this.clientOptions; + } - void setMessageBrowser(ClientOptions options) { - if (options != null) { - transacted = Boolean.parseBoolean(options.getOption(TRANSACTED).getValue()); - if (options.getOption(ClientOptions.MSG_SELECTOR).hasParsedValue()) { - msgSelector = options.getOption(ClientOptions.MSG_SELECTOR).getValue(); - } + void setMessageBrowser(ClientOptions options) { + if (options != null) { + transacted = Boolean.parseBoolean(options.getOption(TRANSACTED).getValue()); + if (options.getOption(ClientOptions.MSG_SELECTOR).hasParsedValue()) { + msgSelector = options.getOption(ClientOptions.MSG_SELECTOR).getValue(); + } + } } - } - @Override - void startClient() { - this.setMessageBrowser(clientOptions); - this.browseMessages(); - } + @Override + void startClient() { + this.setMessageBrowser(clientOptions); + this.browseMessages(); + } - /** - * Browse messages using Queue Browser. - * By default, you browse all actual messages in the queue. - * Messages may be arriving and expiring while the scan is done. - */ - void browseMessages() { - Connection conn = createConnection(clientOptions); - Session ssn = createSession(clientOptions, conn, transacted); - try { - QueueBrowser qBrowser = ssn.createBrowser((Queue) getDestination(), msgSelector); + /** + * Browse messages using Queue Browser. + * By default, you browse all actual messages in the queue. + * Messages may be arriving and expiring while the scan is done. + */ + void browseMessages() { + Connection conn = createConnection(clientOptions); + Session ssn = createSession(clientOptions, conn, transacted); + try { + QueueBrowser qBrowser = ssn.createBrowser((Queue) getDestination(), msgSelector); - conn.start(); + conn.start(); - Enumeration enumMsgs = qBrowser.getEnumeration(); - while (enumMsgs.hasMoreElements()) { - Message msg = (Message) enumMsgs.nextElement(); - CoreClient.printMessage(clientOptions, msg); - } - } catch (JMSException jmse) { - LOG.trace("Exception while browsing messages", jmse); - jmse.printStackTrace(); - System.exit(1); - } finally { - close(conn); + Enumeration enumMsgs = qBrowser.getEnumeration(); + while (enumMsgs.hasMoreElements()) { + Message msg = (Message) enumMsgs.nextElement(); + CoreClient.printMessage(clientOptions, msg); + } + } catch (JMSException jmse) { + LOG.trace("Exception while browsing messages", jmse); + jmse.printStackTrace(); + System.exit(1); + } finally { + close(conn); + } } - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageListenerImpl.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageListenerImpl.java index 693cdc64..dbad785d 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageListenerImpl.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/MessageListenerImpl.java @@ -24,14 +24,14 @@ public class MessageListenerImpl implements MessageListener { - private ReceiverClient rcvrClient; + private ReceiverClient rcvrClient; - MessageListenerImpl(ReceiverClient rcvrClient) { - this.rcvrClient = rcvrClient; - } + MessageListenerImpl(ReceiverClient rcvrClient) { + this.rcvrClient = rcvrClient; + } - @Override - public synchronized void onMessage(Message msg) { - CoreClient.printMessage(rcvrClient.getClientOptions(), msg); - } + @Override + public synchronized void onMessage(Message msg) { + CoreClient.printMessage(rcvrClient.getClientOptions(), msg); + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverClient.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverClient.java index 4d568414..3203187e 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverClient.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverClient.java @@ -32,242 +32,242 @@ */ public class ReceiverClient extends CoreClient { - protected static final String SLEEP_AFTER = "after-receive"; - protected static final String SLEEP_AFTER_ACTION = "after-receive-action"; // TODO not implemented - protected static final String SLEEP_AFTER_TX_ACTION = "after-receive-action-tx-action"; - protected static final String SLEEP_BEFORE = "before-receive"; - - private boolean msgListener; - private boolean durableSubscriber; - private String durableSubscriberPrefix = null; - private boolean unsubscribe = false; - private String durableSubscriberName = null; // passed from user - - /** - * If false, the client(s) consume(s) own message(s). The behavior is undefined for Queue(s). - */ - private boolean noLocal; // TODO implement in future - private boolean transacted; - - private int msgCount; - - /** - * Session.SESSION_TRANSACTED = 0, Session.AUTO_ACKNOWLEDGE = 1, Session.CLIENT_ACKNOWLEDGE = 2, - * Session.DUPS_OK_ACKNOWLEDGE = 3. The last three are non-transactional. - */ - private int txSize; - private String txEndloopAction; - private double closeSleep; - private float duration; - private long timeout; // milliseconds, needs to be greater than 0 - private String durationMode; - private boolean processReplyTo; - - /** - * Selects messages based on the SQL92 syntax subset. Invalid selector causes the client to fail. Example: - * "JMSXDeliveryCount is not null" - */ - private String msgSelector; - private String txAction; - - ReceiverOptions rcvrOpts; - private String writeBinaryMessageFile; - - ReceiverClient(String[] arguments) { - rcvrOpts = new ReceiverOptions(); - ClientOptionManager.applyClientArguments(rcvrOpts, arguments); - String destinationType = rcvrOpts.getOption(DESTINATION_TYPE).getValue(); - LOG.debug("Using destination type:" + destinationType); - } - - @Override - ClientOptions getClientOptions() { - return rcvrOpts; - } - - void setReceiverClient(ClientOptions options) { - // TODO add support for noLocal to ClientOptions - if (options != null) { - msgCount = Integer.parseInt(options.getOption(COUNT).getValue()) > 0 ? Integer.parseInt(options.getOption(COUNT).getValue()) : 0; - msgListener = Boolean.parseBoolean(options.getOption(MSG_LISTENER).getValue()); - durableSubscriber = Boolean.parseBoolean(options.getOption(DURABLE_SUBSCRIBER).getValue()); - durableSubscriberPrefix = options.getOption(DURABLE_SUBSCRIBER_PREFIX).getValue(); - unsubscribe = Boolean.parseBoolean(options.getOption(UNSUBSCRIBE).getValue()); - durableSubscriberName = options.getOption(DURABLE_SUBSCRIBER_NAME).getValue(); -// durableConsumer = Boolean.parseBoolean(options.getOption(DURABLE_CONSUMER).getValue()); JMS 2.0 - msgSelector = options.getOption(MSG_SELECTOR).getValue(); - - closeSleep = Double.parseDouble(options.getOption(CLOSE_SLEEP).getValue()); - closeSleep *= 1000; - duration = Float.parseFloat(options.getOption(DURATION).getValue()); - duration *= 1000; - durationMode = options.getOption(ClientOptions.DURATION_MODE).getValue().toLowerCase(); - - timeout = Long.parseLong(options.getOption(TIMEOUT).getValue()); - if (timeout > 0) timeout *= 1000; - - transacted = Boolean.parseBoolean(options.getOption(TRANSACTED).getValue()); - txAction = options.getOption(TX_ACTION).getValue(); - txSize = Integer.parseInt(options.getOption(TX_SIZE).getValue()); - txEndloopAction = options.getOption(TX_ENDLOOP_ACTION).getValue(); - processReplyTo = Boolean.parseBoolean(options.getOption(PROCESS_REPLY_TO).getValue()); - writeBinaryMessageFile = options.getOption(MSG_BINARY_CONTENT_TO_FILE).getValue(); - } - } - - boolean isAsync() { - return this.msgListener; - } - - @Override - void startClient() { - this.setReceiverClient(rcvrOpts); - // Unsubscribe given durable topic subscriber - if (unsubscribe && durableSubscriberName != null) { - this.unsubscribe(); - } else { - this.consumeMessage(); + protected static final String SLEEP_AFTER = "after-receive"; + protected static final String SLEEP_AFTER_ACTION = "after-receive-action"; // TODO not implemented + protected static final String SLEEP_AFTER_TX_ACTION = "after-receive-action-tx-action"; + protected static final String SLEEP_BEFORE = "before-receive"; + + private boolean msgListener; + private boolean durableSubscriber; + private String durableSubscriberPrefix = null; + private boolean unsubscribe = false; + private String durableSubscriberName = null; // passed from user + + /** + * If false, the client(s) consume(s) own message(s). The behavior is undefined for Queue(s). + */ + private boolean noLocal; // TODO implement in future + private boolean transacted; + + private int msgCount; + + /** + * Session.SESSION_TRANSACTED = 0, Session.AUTO_ACKNOWLEDGE = 1, Session.CLIENT_ACKNOWLEDGE = 2, + * Session.DUPS_OK_ACKNOWLEDGE = 3. The last three are non-transactional. + */ + private int txSize; + private String txEndloopAction; + private double closeSleep; + private float duration; + private long timeout; // milliseconds, needs to be greater than 0 + private String durationMode; + private boolean processReplyTo; + + /** + * Selects messages based on the SQL92 syntax subset. Invalid selector causes the client to fail. Example: + * "JMSXDeliveryCount is not null" + */ + private String msgSelector; + private String txAction; + + ReceiverOptions rcvrOpts; + private String writeBinaryMessageFile; + + ReceiverClient(String[] arguments) { + rcvrOpts = new ReceiverOptions(); + ClientOptionManager.applyClientArguments(rcvrOpts, arguments); + String destinationType = rcvrOpts.getOption(DESTINATION_TYPE).getValue(); + LOG.debug("Using destination type:" + destinationType); } - } - - private void unsubscribe() { - Connection connection = createConnection(rcvrOpts); - Session session = createSession(rcvrOpts, connection, transacted); - try { - session.unsubscribe(durableSubscriberName); - } catch (JMSException e) { - LOG.error("Error while unsubscribing durable subscriptor " + durableSubscriberName); - e.printStackTrace(); - } finally { - close(session); - close(connection); + + @Override + ClientOptions getClientOptions() { + return rcvrOpts; } - } - - /** - * This method contains logic for consuming messages: - creates Connection - creates Session (transacted vs - * non-transacted) - creates MessageConsumer with Destination (topic vs Queue), message selector and support for local - * vs non-local transactions - supports synchronous vs asynchronous (message listener) mode - supports transactions - */ - void consumeMessage() { - Connection conn = createConnection(rcvrOpts); - Session ssn = createSession(rcvrOpts, conn, transacted); - try { - MessageConsumer msgConsumer; - if (durableSubscriber && getDestinationType().equals(ConnectionManager.TOPIC_OBJECT)) { - createSubscriptionName(durableSubscriberPrefix); - msgConsumer = ssn.createDurableSubscriber((Topic) getDestination(), durableSubscriberName, msgSelector, noLocal); - } else { - msgConsumer = ssn.createConsumer(getDestination(), msgSelector, noLocal); - } - MessageListener msgLsnr = new MessageListenerImpl(this); - - if (msgListener) { - msgConsumer.setMessageListener(msgLsnr); - } - - conn.start(); - - //=== ASYNC === - while (msgListener) { - Utils.sleep((int) duration); - } - - //=== SYNC === - int i = 0; - Message msg; - - double initialTimestamp = Utils.getTime(); - do { - if (durationMode.equals(SLEEP_BEFORE)) { - LOG.trace("Sleeping before receive"); - Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + + void setReceiverClient(ClientOptions options) { + // TODO add support for noLocal to ClientOptions + if (options != null) { + msgCount = Integer.parseInt(options.getOption(COUNT).getValue()) > 0 ? Integer.parseInt(options.getOption(COUNT).getValue()) : 0; + msgListener = Boolean.parseBoolean(options.getOption(MSG_LISTENER).getValue()); + durableSubscriber = Boolean.parseBoolean(options.getOption(DURABLE_SUBSCRIBER).getValue()); + durableSubscriberPrefix = options.getOption(DURABLE_SUBSCRIBER_PREFIX).getValue(); + unsubscribe = Boolean.parseBoolean(options.getOption(UNSUBSCRIBE).getValue()); + durableSubscriberName = options.getOption(DURABLE_SUBSCRIBER_NAME).getValue(); +// durableConsumer = Boolean.parseBoolean(options.getOption(DURABLE_CONSUMER).getValue()); JMS 2.0 + msgSelector = options.getOption(MSG_SELECTOR).getValue(); + + closeSleep = Double.parseDouble(options.getOption(CLOSE_SLEEP).getValue()); + closeSleep *= 1000; + duration = Float.parseFloat(options.getOption(DURATION).getValue()); + duration *= 1000; + durationMode = options.getOption(ClientOptions.DURATION_MODE).getValue().toLowerCase(); + + timeout = Long.parseLong(options.getOption(TIMEOUT).getValue()); + if (timeout > 0) timeout *= 1000; + + transacted = Boolean.parseBoolean(options.getOption(TRANSACTED).getValue()); + txAction = options.getOption(TX_ACTION).getValue(); + txSize = Integer.parseInt(options.getOption(TX_SIZE).getValue()); + txEndloopAction = options.getOption(TX_ENDLOOP_ACTION).getValue(); + processReplyTo = Boolean.parseBoolean(options.getOption(PROCESS_REPLY_TO).getValue()); + writeBinaryMessageFile = options.getOption(MSG_BINARY_CONTENT_TO_FILE).getValue(); } + } + + boolean isAsync() { + return this.msgListener; + } - if (timeout == 0) { - // TODO JMS SPEC BUG https://java.net/jira/browse/JMS_SPEC-85 - // msg = msgConsumer.receiveNoWait(); - msg = msgConsumer.receive(200); // the lowest number of ms to receive a message was 36ms - } else if (timeout == -1) { - msg = msgConsumer.receive(); // == msgConsumer.receive(0) + @Override + void startClient() { + this.setReceiverClient(rcvrOpts); + // Unsubscribe given durable topic subscriber + if (unsubscribe && durableSubscriberName != null) { + this.unsubscribe(); } else { - msg = msgConsumer.receive(timeout); + this.consumeMessage(); } + } - if (durationMode.equals(SLEEP_AFTER)) { - LOG.trace("Sleeping after receive"); - Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + private void unsubscribe() { + Connection connection = createConnection(rcvrOpts); + Session session = createSession(rcvrOpts, connection, transacted); + try { + session.unsubscribe(durableSubscriberName); + } catch (JMSException e) { + LOG.error("Error while unsubscribing durable subscriptor " + durableSubscriberName); + e.printStackTrace(); + } finally { + close(session); + close(connection); } + } - if (ssn.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE && msg != null) { - msg.acknowledge(); - } + /** + * This method contains logic for consuming messages: - creates Connection - creates Session (transacted vs + * non-transacted) - creates MessageConsumer with Destination (topic vs Queue), message selector and support for local + * vs non-local transactions - supports synchronous vs asynchronous (message listener) mode - supports transactions + */ + void consumeMessage() { + Connection conn = createConnection(rcvrOpts); + Session ssn = createSession(rcvrOpts, conn, transacted); + try { + MessageConsumer msgConsumer; + if (durableSubscriber && getDestinationType().equals(ConnectionManager.TOPIC_OBJECT)) { + createSubscriptionName(durableSubscriberPrefix); + msgConsumer = ssn.createDurableSubscriber((Topic) getDestination(), durableSubscriberName, msgSelector, noLocal); + } else { + msgConsumer = ssn.createConsumer(getDestination(), msgSelector, noLocal); + } + MessageListener msgLsnr = new MessageListenerImpl(this); - if (msg != null) { - if (!writeBinaryMessageFile.isEmpty()) { - Utils.writeBinaryContentToFile(writeBinaryMessageFile, msg, i); - } - i++; - printMessage(rcvrOpts, msg); - } else { - LOG.trace("Did not receive any message!"); - } + if (msgListener) { + msgConsumer.setMessageListener(msgLsnr); + } - //=== TRANSACTION === - if (ssn.getTransacted() && txSize != 0) { - if (i % txSize == 0) { - CoreClient.doTransaction(ssn, txAction); + conn.start(); - if (durationMode.equals(SLEEP_AFTER_TX_ACTION)) { - LOG.trace("Sleeping after transaction"); - Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + //=== ASYNC === + while (msgListener) { + Utils.sleep((int) duration); } - } - } - //=== REPLY TO === - if (processReplyTo && msg != null && msg.getJMSReplyTo() != null) { - MessageProducer msgProducer = ssn.createProducer(msg.getJMSReplyTo()); - msg.setJMSReplyTo(null); - msgProducer.send(msg); - close(msgProducer); + //=== SYNC === + int i = 0; + Message msg; + + double initialTimestamp = Utils.getTime(); + do { + if (durationMode.equals(SLEEP_BEFORE)) { + LOG.trace("Sleeping before receive"); + Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + } + + if (timeout == 0) { + // TODO JMS SPEC BUG https://java.net/jira/browse/JMS_SPEC-85 + // msg = msgConsumer.receiveNoWait(); + msg = msgConsumer.receive(200); // the lowest number of ms to receive a message was 36ms + } else if (timeout == -1) { + msg = msgConsumer.receive(); // == msgConsumer.receive(0) + } else { + msg = msgConsumer.receive(timeout); + } + + if (durationMode.equals(SLEEP_AFTER)) { + LOG.trace("Sleeping after receive"); + Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + } + + if (ssn.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE && msg != null) { + msg.acknowledge(); + } + + if (msg != null) { + if (!writeBinaryMessageFile.isEmpty()) { + Utils.writeBinaryContentToFile(writeBinaryMessageFile, msg, i); + } + i++; + printMessage(rcvrOpts, msg); + } else { + LOG.trace("Did not receive any message!"); + } + + //=== TRANSACTION === + if (ssn.getTransacted() && txSize != 0) { + if (i % txSize == 0) { + CoreClient.doTransaction(ssn, txAction); + + if (durationMode.equals(SLEEP_AFTER_TX_ACTION)) { + LOG.trace("Sleeping after transaction"); + Utils.sleepUntilNextIteration(initialTimestamp, msgCount, duration, i + 1); + } + } + } + + //=== REPLY TO === + if (processReplyTo && msg != null && msg.getJMSReplyTo() != null) { + MessageProducer msgProducer = ssn.createProducer(msg.getJMSReplyTo()); + msg.setJMSReplyTo(null); + msgProducer.send(msg); + close(msgProducer); + } + + if (i == msgCount) { + close(msgConsumer); + break; // or timeout + } + } while (msg != null); + + if (ssn.getTransacted()) { + LOG.trace("Performing tx-endloop-action " + txEndloopAction); + CoreClient.doTransaction(ssn, txEndloopAction); + } + } catch (InvalidSelectorException se) { + LOG.error("Invalid selector \"{}\" has been specified.", msgSelector); + se.printStackTrace(); + System.exit(2); + } catch (JMSException jmse) { + LOG.error("Exception while consuming message!"); + jmse.printStackTrace(); + System.exit(1); + } finally { + if (closeSleep > 0) { + Utils.sleep((int) closeSleep); + } + close(ssn); + close(conn); } + } - if (i == msgCount) { - close(msgConsumer); - break; // or timeout + private void createSubscriptionName(String customPrefix) { + if (durableSubscriberName == null) { + UUID uuid = UUID.randomUUID(); + if (customPrefix == null || customPrefix.equals("")) + durableSubscriberName = "qpid-jms-" + uuid.toString(); + else + durableSubscriberName = customPrefix + uuid.toString(); } - } while (msg != null); - - if (ssn.getTransacted()) { - LOG.trace("Performing tx-endloop-action " + txEndloopAction); - CoreClient.doTransaction(ssn, txEndloopAction); - } - } catch (InvalidSelectorException se) { - LOG.error("Invalid selector \"{}\" has been specified.", msgSelector); - se.printStackTrace(); - System.exit(2); - } catch (JMSException jmse) { - LOG.error("Exception while consuming message!"); - jmse.printStackTrace(); - System.exit(1); - } finally { - if (closeSleep > 0) { - Utils.sleep((int) closeSleep); - } - close(ssn); - close(conn); - } - } - - private void createSubscriptionName(String customPrefix) { - if (durableSubscriberName == null) { - UUID uuid = UUID.randomUUID(); - if (customPrefix == null || customPrefix.equals("")) - durableSubscriberName = "qpid-jms-" + uuid.toString(); - else - durableSubscriberName = customPrefix + uuid.toString(); + LOG.debug("DurableSubscriptionName=" + durableSubscriberName); } - LOG.debug("DurableSubscriptionName=" + durableSubscriberName); - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverOptions.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverOptions.java index c83ff4a7..ffc07b15 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverOptions.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/ReceiverOptions.java @@ -29,99 +29,99 @@ * Constructed from CommonOptions and receiverDefaultOptions. */ public class ReceiverOptions extends ClientOptions { - private List options = null; - private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); - private final List receiverDefaultOptions = new ArrayList(); + private List options = null; + private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); + private final List receiverDefaultOptions = new ArrayList(); - { - receiverDefaultOptions.addAll(Arrays.asList( + { + receiverDefaultOptions.addAll(Arrays.asList( // - new com.redhat.mqe.lib.Option(ADDRESS, "a", "ADDRESS", "", "Queue/Topic destination"), - new com.redhat.mqe.lib.Option(TIMEOUT, "t", "TIMEOUT", "0", "timeout in seconds to wait before exiting"), - new com.redhat.mqe.lib.Option("forever", "f", "", "false", "DEPRECATED! use \"timeout -1\" ignore timeout and wait forever"), - new com.redhat.mqe.lib.Option(ACTION, "", "ACTION", "acknowledge", "action on acquired message (default ack)"), - new com.redhat.mqe.lib.Option(COUNT, "c", "MESSAGES", "0", "read c messages, then exit (default 0 for all messages)"), - new com.redhat.mqe.lib.Option(DURATION, "d", "DURATION", "0", "message actions total duration in seconds (defines msg-rate together with count)"), - new com.redhat.mqe.lib.Option(LOG_MSGS, "", "LOGMSGFMT", "upstream", "message[s] reporting style (dict|body|upstream|none)"), - new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "upstream", "report various statistic/debug information"), - new com.redhat.mqe.lib.Option(TX_SIZE, "", "TXBSIZE", "0", "transactional mode: batch message count size (negative skips tx-action before exit)"), - new com.redhat.mqe.lib.Option(TX_ACTION, "", "TXACTION", "commit", "transactional action at the end of tx batch"), - new com.redhat.mqe.lib.Option(TX_ENDLOOP_ACTION, "", "TXACTION", "None", "transactional action after sending all messages in loop (commit|rollback|recover|None)"), - new com.redhat.mqe.lib.Option(DURATION_MODE, "", "VALUE", ReceiverClient.SLEEP_AFTER, "specifies where to wait (" + ReceiverClient.SLEEP_BEFORE - + "/" + ReceiverClient.SLEEP_AFTER + "/" + ReceiverClient.SLEEP_AFTER_ACTION + "/" + ReceiverClient.SLEEP_AFTER_TX_ACTION + ")"), - new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SYNCMODE", "action", "synchronization mode: none/session/action/persistent/transient"), - new com.redhat.mqe.lib.Option(MSG_LISTENER, "", "ENABLED", "false", "receive messages using a MessageListener"), - new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER, "", "ENABLED", "false", "create durable subscription to topic"), - new com.redhat.mqe.lib.Option(UNSUBSCRIBE, "", "UNSUBSCRIBE", "false", "unsubscribe durable subscriptor with given name (provide " + DURABLE_SUBSCRIBER_NAME +")"), - new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER_PREFIX, "", "PREFIX", "", "prefix to use to identify this connection subscriber"), - new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER_NAME, "", "PREFIX", "", "name of the durable subscriber to be unsubscribe"), + new com.redhat.mqe.lib.Option(ADDRESS, "a", "ADDRESS", "", "Queue/Topic destination"), + new com.redhat.mqe.lib.Option(TIMEOUT, "t", "TIMEOUT", "0", "timeout in seconds to wait before exiting"), + new com.redhat.mqe.lib.Option("forever", "f", "", "false", "DEPRECATED! use \"timeout -1\" ignore timeout and wait forever"), + new com.redhat.mqe.lib.Option(ACTION, "", "ACTION", "acknowledge", "action on acquired message (default ack)"), + new com.redhat.mqe.lib.Option(COUNT, "c", "MESSAGES", "0", "read c messages, then exit (default 0 for all messages)"), + new com.redhat.mqe.lib.Option(DURATION, "d", "DURATION", "0", "message actions total duration in seconds (defines msg-rate together with count)"), + new com.redhat.mqe.lib.Option(LOG_MSGS, "", "LOGMSGFMT", "upstream", "message[s] reporting style (dict|body|upstream|none)"), + new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "upstream", "report various statistic/debug information"), + new com.redhat.mqe.lib.Option(TX_SIZE, "", "TXBSIZE", "0", "transactional mode: batch message count size (negative skips tx-action before exit)"), + new com.redhat.mqe.lib.Option(TX_ACTION, "", "TXACTION", "commit", "transactional action at the end of tx batch"), + new com.redhat.mqe.lib.Option(TX_ENDLOOP_ACTION, "", "TXACTION", "None", "transactional action after sending all messages in loop (commit|rollback|recover|None)"), + new com.redhat.mqe.lib.Option(DURATION_MODE, "", "VALUE", ReceiverClient.SLEEP_AFTER, "specifies where to wait (" + ReceiverClient.SLEEP_BEFORE + + "/" + ReceiverClient.SLEEP_AFTER + "/" + ReceiverClient.SLEEP_AFTER_ACTION + "/" + ReceiverClient.SLEEP_AFTER_TX_ACTION + ")"), + new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SYNCMODE", "action", "synchronization mode: none/session/action/persistent/transient"), + new com.redhat.mqe.lib.Option(MSG_LISTENER, "", "ENABLED", "false", "receive messages using a MessageListener"), + new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER, "", "ENABLED", "false", "create durable subscription to topic"), + new com.redhat.mqe.lib.Option(UNSUBSCRIBE, "", "UNSUBSCRIBE", "false", "unsubscribe durable subscriptor with given name (provide " + DURABLE_SUBSCRIBER_NAME + ")"), + new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER_PREFIX, "", "PREFIX", "", "prefix to use to identify this connection subscriber"), + new com.redhat.mqe.lib.Option(DURABLE_SUBSCRIBER_NAME, "", "PREFIX", "", "name of the durable subscriber to be unsubscribe"), // new Option(DURABLE_CONSUMER, "", "ENABLED", "false", "create durable consumer from topic"), JMS 2.0 - new com.redhat.mqe.lib.Option(MSG_SELECTOR, "", "SELECT", "", "select messages based on the SQL92 subset"), - new com.redhat.mqe.lib.Option("verbose", "", "", "false", "DEPRECATED? verbose AMQP message output"), - new com.redhat.mqe.lib.Option(CAPACITY, "", "CAPACITY", "-1", "sender|receiver capacity (no effect in jms atm)"), - new com.redhat.mqe.lib.Option(BROWSER, "", "ENABLED", "false", "if true, browse messages instead of reading"), - new com.redhat.mqe.lib.Option(PROCESS_REPLY_TO, "", null, "", "whether to process reply to (true) or ignore it"), - new com.redhat.mqe.lib.Option(MSG_BINARY_CONTENT_TO_FILE, "", "FILEPATH", "", "write binary data to provided file with prefix") - )); + new com.redhat.mqe.lib.Option(MSG_SELECTOR, "", "SELECT", "", "select messages based on the SQL92 subset"), + new com.redhat.mqe.lib.Option("verbose", "", "", "false", "DEPRECATED? verbose AMQP message output"), + new com.redhat.mqe.lib.Option(CAPACITY, "", "CAPACITY", "-1", "sender|receiver capacity (no effect in jms atm)"), + new com.redhat.mqe.lib.Option(BROWSER, "", "ENABLED", "false", "if true, browse messages instead of reading"), + new com.redhat.mqe.lib.Option(PROCESS_REPLY_TO, "", null, "", "whether to process reply to (true) or ignore it"), + new com.redhat.mqe.lib.Option(MSG_BINARY_CONTENT_TO_FILE, "", "FILEPATH", "", "write binary data to provided file with prefix") + )); // receiverDefaultOptions.put("forever", "false"); // drain only option // receiverDefaultOptions.put("action", "acknowledge"); // acknowledge, reject, release, noack - } + } - public ReceiverOptions() { - this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), receiverDefaultOptions); - /** - -h, --help show this help message and exit - -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) - -t TIMEOUT, --timeout TIMEOUT timeout in seconds to wait before exiting (default 0) - -f, --forever ignore timeout and wait forever - -c COUNT, --count COUNT read c messages, then exit (default 0) - --duration DURATION message actions total duration (defines msg-rate together with count) (default 0) - --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all - --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI - --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) - --accept ACTION action on acquired message (default ack) - -log-msgs LOGMSGFMT message[s] reporting style (dict|body|upstream|none) (default upstream) - * --log-stats LEVEL report various statistic/debug information (default ) - --tx-batch-size TXBSIZE transactional mode: batch message count size (negative skips tx-action before exit) (default 0) - --tx-action TXACTION transactional action at the end of tx batch (default commit) - --sync-mode SMODE synchronization mode: none/session/action/persistent/transient (default action) - --msg-listener-ena receive messages using a MessageListener - --verbose verbose AMQP message output - --capacity CPCT sender|receiver capacity (no effect in jms atm) (default -1) - --close-sleep CSLEEP sleep before publisher/subscriber/session/connection.close() (default 0) - TODO * - */ - } + public ReceiverOptions() { + this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), receiverDefaultOptions); + /** + -h, --help show this help message and exit + -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) + -t TIMEOUT, --timeout TIMEOUT timeout in seconds to wait before exiting (default 0) + -f, --forever ignore timeout and wait forever + -c COUNT, --count COUNT read c messages, then exit (default 0) + --duration DURATION message actions total duration (defines msg-rate together with count) (default 0) + --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all + --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI + --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) + --accept ACTION action on acquired message (default ack) + -log-msgs LOGMSGFMT message[s] reporting style (dict|body|upstream|none) (default upstream) + * --log-stats LEVEL report various statistic/debug information (default ) + --tx-batch-size TXBSIZE transactional mode: batch message count size (negative skips tx-action before exit) (default 0) + --tx-action TXACTION transactional action at the end of tx batch (default commit) + --sync-mode SMODE synchronization mode: none/session/action/persistent/transient (default action) + --msg-listener-ena receive messages using a MessageListener + --verbose verbose AMQP message output + --capacity CPCT sender|receiver capacity (no effect in jms atm) (default -1) + --close-sleep CSLEEP sleep before publisher/subscriber/session/connection.close() (default 0) + TODO * + */ + } - @Override - public com.redhat.mqe.lib.Option getOption(String name) { - if (name != null) { - for (com.redhat.mqe.lib.Option option : options) { - if (name.equals(option.getName())) - return option; - } - } else { - LOG.error("Accessing client options map with null key."); - throw new IllegalArgumentException("Null name is not allowed!"); + @Override + public com.redhat.mqe.lib.Option getOption(String name) { + if (name != null) { + for (com.redhat.mqe.lib.Option option : options) { + if (name.equals(option.getName())) + return option; + } + } else { + LOG.error("Accessing client options map with null key."); + throw new IllegalArgumentException("Null name is not allowed!"); + } + return null; } - return null; - } - @Override - public List getClientDefaultOptions() { - return receiverDefaultOptions; - } + @Override + public List getClientDefaultOptions() { + return receiverDefaultOptions; + } - @Override - public List getClientOptions() { - return options; - } + @Override + public List getClientOptions() { + return options; + } - @Override - public String toString() { - return "ReceiverOptions{" + - "options=" + options; - } + @Override + public String toString() { + return "ReceiverOptions{" + + "options=" + options; + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderClient.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderClient.java index c042ed06..44c21849 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderClient.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderClient.java @@ -42,569 +42,571 @@ * of settings of these messages. */ public class SenderClient extends CoreClient { - private SenderOptions senderOptions; - private static List content; - private static boolean isEmptyMessage = false; - private boolean userMessageCounter = false; - private String userMessageCounterText; - private static byte[] binaryMessageData; - static final String QPID_SUBJECT = "qpid.subject"; - static final String AMQ_SUBJECT = "JMS_AMQP_Subject"; - static final String BEFORE_SEND = "before-send"; - static final String AFTER_SEND = "after-send"; - static final String AFTER_SEND_TX_ACTION = "after-send-tx-action"; - - - public SenderClient(String[] arguments) { - senderOptions = new SenderOptions(); - ClientOptionManager.applyClientArguments(senderOptions, arguments); - } - - /** - * Initial method to start the client. - * Initialization of content, properties and everything about - * how to send message is done/initiated by this method. - * Contains the main sending loop method. - */ - void startClient() { - ClientOptions senderOptions = this.getClientOptions(); - setGlobalClientOptions(senderOptions); - Connection connection = this.createConnection(senderOptions); - - // Transactions support - int transactionSize = 0; - String transaction = null; - if (senderOptions.getOption(ClientOptions.TX_SIZE).hasParsedValue() - || senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).hasParsedValue()) { - transactionSize = Integer.parseInt(senderOptions.getOption(ClientOptions.TX_SIZE).getValue()); - if (senderOptions.getOption(ClientOptions.TX_ACTION).hasParsedValue()) { - transaction = senderOptions.getOption(ClientOptions.TX_ACTION).getValue().toLowerCase(); - } else { - transaction = senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).getValue().toLowerCase(); - } + private SenderOptions senderOptions; + private static List content; + private static boolean isEmptyMessage = false; + private boolean userMessageCounter = false; + private String userMessageCounterText; + private static byte[] binaryMessageData; + static final String QPID_SUBJECT = "qpid.subject"; + static final String AMQ_SUBJECT = "JMS_AMQP_Subject"; + static final String BEFORE_SEND = "before-send"; + static final String AFTER_SEND = "after-send"; + static final String AFTER_SEND_TX_ACTION = "after-send-tx-action"; + + + public SenderClient(String[] arguments) { + senderOptions = new SenderOptions(); + ClientOptionManager.applyClientArguments(senderOptions, arguments); } - try { - Session session = (transaction == null || transaction.equals("none")) ? - this.createSession(senderOptions, connection, false) : this.createSession(senderOptions, connection, true); - connection.start(); - MessageProducer msgProducer = session.createProducer(this.getDestination()); - setMessageProducer(senderOptions, msgProducer); - - // check if not empty message - if (!(isEmptyMessage = checkForEmptyMessage(senderOptions))) { - // Create message content from provided input - createMessageContent(senderOptions); - } else { - content = new ArrayList<>(); - } - - // Calculate msg-rate from COUNT & DURATION - double initialTimestamp = Utils.getTime(); - int count = Integer.parseInt(senderOptions.getOption(ClientOptions.COUNT).getValue()); - double duration = Double.parseDouble(senderOptions.getOption(ClientOptions.DURATION).getValue()); - duration *= 1000; // convert to milliseconds - - // Create message and fill body with data (content) - Message message = this.createMessage(senderOptions, session); - this.setMessageProperties(message); - this.setCustomMessageProperties(message); - - int msgCounter = 0; - String durationMode = senderOptions.getOption(ClientOptions.DURATION_MODE).getValue(); - while (true) { - // Set user defined message auto counter - if (userMessageCounter && (message instanceof TextMessage)) { - ((TextMessage) message).setText(String.format(userMessageCounterText, msgCounter)); - } - // TODO Set variable message properties - have not found any so far.. - // sleep for given amount of time, defined by msg-rate "before-send" - if (durationMode.equals(BEFORE_SEND)) { - LOG.trace("Sleeping before send"); - Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); + /** + * Initial method to start the client. + * Initialization of content, properties and everything about + * how to send message is done/initiated by this method. + * Contains the main sending loop method. + */ + void startClient() { + ClientOptions senderOptions = this.getClientOptions(); + setGlobalClientOptions(senderOptions); + Connection connection = this.createConnection(senderOptions); + + // Transactions support + int transactionSize = 0; + String transaction = null; + if (senderOptions.getOption(ClientOptions.TX_SIZE).hasParsedValue() + || senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).hasParsedValue()) { + transactionSize = Integer.parseInt(senderOptions.getOption(ClientOptions.TX_SIZE).getValue()); + if (senderOptions.getOption(ClientOptions.TX_ACTION).hasParsedValue()) { + transaction = senderOptions.getOption(ClientOptions.TX_ACTION).getValue().toLowerCase(); + } else { + transaction = senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).getValue().toLowerCase(); + } } - // Send messages - msgProducer.send(message); - msgCounter++; - // Makes message body read only from write only mode - if (message instanceof StreamMessage) { - ((StreamMessage) message).reset(); - } - if (message instanceof BytesMessage) { - ((BytesMessage) message).reset(); - } - printMessage(senderOptions, message); - // sleep for given amount of time, defined by msg-rate "after-send-before-tx-action" - if (durationMode.equals(AFTER_SEND)) { - LOG.trace("Sleeping after send"); - Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); - } + try { + Session session = (transaction == null || transaction.equals("none")) ? + this.createSession(senderOptions, connection, false) : this.createSession(senderOptions, connection, true); + connection.start(); + MessageProducer msgProducer = session.createProducer(this.getDestination()); + setMessageProducer(senderOptions, msgProducer); + + // check if not empty message + if (!(isEmptyMessage = checkForEmptyMessage(senderOptions))) { + // Create message content from provided input + createMessageContent(senderOptions); + } else { + content = new ArrayList<>(); + } - // TX support - if (transaction != null && transactionSize != 0) { - if (msgCounter % transactionSize == 0) { - // Do transaction action - doTransaction(session, transaction); - } - } - // sleep for given amount of time, defined by msg-rate "after-send-after-tx-action" - if (durationMode.equals(AFTER_SEND_TX_ACTION)) { - LOG.trace("Sleeping after send & tx action"); - Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); + // Calculate msg-rate from COUNT & DURATION + double initialTimestamp = Utils.getTime(); + int count = Integer.parseInt(senderOptions.getOption(ClientOptions.COUNT).getValue()); + double duration = Double.parseDouble(senderOptions.getOption(ClientOptions.DURATION).getValue()); + duration *= 1000; // convert to milliseconds + + // Create message and fill body with data (content) + Message message = this.createMessage(senderOptions, session); + this.setMessageProperties(message); + this.setCustomMessageProperties(message); + + int msgCounter = 0; + String durationMode = senderOptions.getOption(ClientOptions.DURATION_MODE).getValue(); + while (true) { + // Set user defined message auto counter + if (userMessageCounter && (message instanceof TextMessage)) { + ((TextMessage) message).setText(String.format(userMessageCounterText, msgCounter)); + } + // TODO Set variable message properties - have not found any so far.. + // sleep for given amount of time, defined by msg-rate "before-send" + if (durationMode.equals(BEFORE_SEND)) { + LOG.trace("Sleeping before send"); + Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); + } + + // Send messages + msgProducer.send(message); + msgCounter++; + // Makes message body read only from write only mode + if (message instanceof StreamMessage) { + ((StreamMessage) message).reset(); + } + if (message instanceof BytesMessage) { + ((BytesMessage) message).reset(); + } + printMessage(senderOptions, message); + // sleep for given amount of time, defined by msg-rate "after-send-before-tx-action" + if (durationMode.equals(AFTER_SEND)) { + LOG.trace("Sleeping after send"); + Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); + } + + // TX support + if (transaction != null && transactionSize != 0) { + if (msgCounter % transactionSize == 0) { + // Do transaction action + doTransaction(session, transaction); + } + } + // sleep for given amount of time, defined by msg-rate "after-send-after-tx-action" + if (durationMode.equals(AFTER_SEND_TX_ACTION)) { + LOG.trace("Sleeping after send & tx action"); + Utils.sleepUntilNextIteration(initialTimestamp, count, duration, msgCounter + 1); + } + if (count == 0) continue; + if (msgCounter == count) break; + } + + // Finish transaction with sending of the rest messages + if (transaction != null) { + doTransaction(session, senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).getValue()); + } + } catch (JMSException | IllegalArgumentException jmse) { + LOG.error("Error while sending a message!", jmse.getMessage()); + jmse.printStackTrace(); + System.exit(1); + } finally { + double closeSleep = Double.parseDouble(this.getClientOptions().getOption(ClientOptions.CLOSE_SLEEP).getValue()); + closeConnObjects(this, closeSleep); + this.close(connection); } - if (count == 0) continue; - if (msgCounter == count) break; - } - - // Finish transaction with sending of the rest messages - if (transaction != null) { - doTransaction(session, senderOptions.getOption(ClientOptions.TX_ENDLOOP_ACTION).getValue()); - } - } catch (JMSException | IllegalArgumentException jmse) { - LOG.error("Error while sending a message!", jmse.getMessage()); - jmse.printStackTrace(); - System.exit(1); - } finally { - double closeSleep = Double.parseDouble(this.getClientOptions().getOption(ClientOptions.CLOSE_SLEEP).getValue()); - closeConnObjects(this, closeSleep); - this.close(connection); } - } - - /** - * Set default priority, ttl, durability and creating of id, - * timestamps for messages of this message producer. - * - * @param senderOptions specify defined options for messages & messageProducers - * @param producer set this message producer - */ - private static void setMessageProducer(ClientOptions senderOptions, MessageProducer producer) { - try { - // set delivery mode - durable/non-durable - String deliveryModeArg = senderOptions.getOption(ClientOptions.MSG_DURABLE).getValue().toLowerCase(); - int deliveryMode = (deliveryModeArg.equals("true") || deliveryModeArg.equals("yes")) - ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT; - producer.setDeliveryMode(deliveryMode); - // set time to live of message if provided - if (senderOptions.getOption(ClientOptions.MSG_TTL).hasParsedValue()) { - producer.setTimeToLive(Long.parseLong(senderOptions.getOption(ClientOptions.MSG_TTL).getValue())); - } - // set message priority if provided - if (senderOptions.getOption(ClientOptions.MSG_PRIORITY).hasParsedValue()) { - int priority = Integer.parseInt(senderOptions.getOption(ClientOptions.MSG_PRIORITY).getValue()); - if (priority < 0 || priority > 10) { - LOG.warn("Message priority is not in JMS interval <0, 10>."); - } - producer.setPriority(priority); - } - // Set Message ID or disable it completely - if (senderOptions.getOption(ClientOptions.MSG_ID).hasParsedValue()) { - if (senderOptions.getOption(ClientOptions.MSG_ID).getValue().equals("noid")) { - producer.setDisableMessageID(true); + + /** + * Set default priority, ttl, durability and creating of id, + * timestamps for messages of this message producer. + * + * @param senderOptions specify defined options for messages & messageProducers + * @param producer set this message producer + */ + private static void setMessageProducer(ClientOptions senderOptions, MessageProducer producer) { + try { + // set delivery mode - durable/non-durable + String deliveryModeArg = senderOptions.getOption(ClientOptions.MSG_DURABLE).getValue().toLowerCase(); + int deliveryMode = (deliveryModeArg.equals("true") || deliveryModeArg.equals("yes")) + ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT; + producer.setDeliveryMode(deliveryMode); + // set time to live of message if provided + if (senderOptions.getOption(ClientOptions.MSG_TTL).hasParsedValue()) { + producer.setTimeToLive(Long.parseLong(senderOptions.getOption(ClientOptions.MSG_TTL).getValue())); + } + // set message priority if provided + if (senderOptions.getOption(ClientOptions.MSG_PRIORITY).hasParsedValue()) { + int priority = Integer.parseInt(senderOptions.getOption(ClientOptions.MSG_PRIORITY).getValue()); + if (priority < 0 || priority > 10) { + LOG.warn("Message priority is not in JMS interval <0, 10>."); + } + producer.setPriority(priority); + } + // Set Message ID or disable it completely + if (senderOptions.getOption(ClientOptions.MSG_ID).hasParsedValue()) { + if (senderOptions.getOption(ClientOptions.MSG_ID).getValue().equals("noid")) { + producer.setDisableMessageID(true); + } + } + // Producer does not generate timestamps - for performance only + producer.setDisableMessageTimestamp( + Boolean.parseBoolean(senderOptions.getOption(ClientOptions.MSG_NOTIMESTAMP).getValue())); + } catch (JMSException e) { + e.printStackTrace(); } - } - // Producer does not generate timestamps - for performance only - producer.setDisableMessageTimestamp( - Boolean.parseBoolean(senderOptions.getOption(ClientOptions.MSG_NOTIMESTAMP).getValue())); - } catch (JMSException e) { - e.printStackTrace(); } - } - - /** - * Method creates message based on provided content on given session. - * - * @param senderOptions specify defined options for messages & messageProducers - * @param session to which message will belong - * @return newly created and set up message to be sent - */ - @SuppressWarnings("unchecked") - private T createMessage(ClientOptions senderOptions, Session session) { - try { - if (senderOptions.getOption(com.redhat.mqe.lib.ClientOptions.MSG_CONTENT_BINARY).hasParsedValue()) { - BytesMessage bytesMessage = session.createBytesMessage(); - fillBytesMessage(senderOptions, bytesMessage); - return (T) bytesMessage; - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT).hasParsedValue() - || senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).hasParsedValue()) { + + /** + * Method creates message based on provided content on given session. + * + * @param senderOptions specify defined options for messages & messageProducers + * @param session to which message will belong + * @return newly created and set up message to be sent + */ + @SuppressWarnings("unchecked") + private T createMessage(ClientOptions senderOptions, Session session) { + try { + if (senderOptions.getOption(com.redhat.mqe.lib.ClientOptions.MSG_CONTENT_BINARY).hasParsedValue()) { + BytesMessage bytesMessage = session.createBytesMessage(); + fillBytesMessage(senderOptions, bytesMessage); + return (T) bytesMessage; + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT).hasParsedValue() + || senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).hasParsedValue()) { // if (senderOptions.getOption(ClientOptions.CONTENT_TYPE).hasParsedValue()) { - String textContent; - switch (senderOptions.getOption(ClientOptions.CONTENT_TYPE).getValue().toLowerCase()) { - case "string": - TextMessage textMessage = session.createTextMessage(); - textContent = content.get(0).getValue().toString(); - String pattern = "%[ 0-9]*d"; - Pattern r = Pattern.compile(pattern); - Matcher matcher = r.matcher(textContent); - - if (matcher.find()) { - userMessageCounter = true; - userMessageCounterText = textContent; - } - textMessage.setText(textContent); - return (T) textMessage; - case "object": - case "int": - case "integer": - case "long": - case "float": - case "double": - case "bool": - ObjectMessage objectMessage = session.createObjectMessage(); - fillObjectMessage(senderOptions, objectMessage); - return (T) objectMessage; - } + String textContent; + switch (senderOptions.getOption(ClientOptions.CONTENT_TYPE).getValue().toLowerCase()) { + case "string": + TextMessage textMessage = session.createTextMessage(); + textContent = content.get(0).getValue().toString(); + String pattern = "%[ 0-9]*d"; + Pattern r = Pattern.compile(pattern); + Matcher matcher = r.matcher(textContent); + + if (matcher.find()) { + userMessageCounter = true; + userMessageCounterText = textContent; + } + textMessage.setText(textContent); + return (T) textMessage; + case "object": + case "int": + case "integer": + case "long": + case "float": + case "double": + case "bool": + ObjectMessage objectMessage = session.createObjectMessage(); + fillObjectMessage(senderOptions, objectMessage); + return (T) objectMessage; + } // } - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { - // Create "ListMessage" using StreamMessage - StreamMessage pseudoListMessage = session.createStreamMessage(); - for (Content c : content) { - pseudoListMessage.writeObject(c.getValue()); - } - return (T) pseudoListMessage; - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { - MapMessage mapMessage = session.createMapMessage(); - if (!isEmptyMessage) { - fillMapMessage(senderOptions, mapMessage); + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { + // Create "ListMessage" using StreamMessage + StreamMessage pseudoListMessage = session.createStreamMessage(); + for (Content c : content) { + pseudoListMessage.writeObject(c.getValue()); + } + return (T) pseudoListMessage; + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { + MapMessage mapMessage = session.createMapMessage(); + if (!isEmptyMessage) { + fillMapMessage(senderOptions, mapMessage); + } + return (T) mapMessage; + } else { + LOG.trace("Unknown type of message should be created! Sending empty Message"); + return (T) session.createMessage(); + } + } catch (JMSException e) { + LOG.error("Error while creating message or setting content to this message!"); + e.printStackTrace(); } - return (T) mapMessage; - } else { - LOG.trace("Unknown type of message should be created! Sending empty Message"); - return (T) session.createMessage(); - } - } catch (JMSException e) { - LOG.error("Error while creating message or setting content to this message!"); - e.printStackTrace(); + return null; } - return null; - } - - /** - * Create & return empty Map/ListMessage - * - * @param senderOptions options of the sender - * @return empty MapMessage or ListMessage - */ - private static boolean checkForEmptyMessage(ClientOptions senderOptions) { - List values; - if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { - values = senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).getParsedValuesList(); - if (isEmptyMessage(values)) { - return true; - } - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { - values = senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).getParsedValuesList(); - if (isEmptyMessage(values)) { - // createEmptyListMessage; - return true; - } + + /** + * Create & return empty Map/ListMessage + * + * @param senderOptions options of the sender + * @return empty MapMessage or ListMessage + */ + private static boolean checkForEmptyMessage(ClientOptions senderOptions) { + List values; + if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { + values = senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).getParsedValuesList(); + if (isEmptyMessage(values)) { + return true; + } + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { + values = senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).getParsedValuesList(); + if (isEmptyMessage(values)) { + // createEmptyListMessage; + return true; + } + } + return false; } - return false; - } - - /** - * Returns whether the list of Strings is empty. - * - * @param values list to be checked for emptiness - * @return true if the list is empty, false otherwise - */ - private static boolean isEmptyMessage(List values) { - return (values.size() == 1 - && (values.get(0).equals("") || values.get(0).equals("\"\"") || values.get(0).equals("\'\'"))); - } - - /** - * Fill object message with data. - * - * @param senderOptions - * @param objectMessage - */ - private void fillObjectMessage(ClientOptions senderOptions, ObjectMessage objectMessage) { - try { - LOG.debug("Filling object data"); - if (content.size() == 1) { - objectMessage.setObject((Serializable) content.get(0).getValue()); - } else { - LOG.error("Content is bigger then one object. " + - "Don't know how to set for object message multiple data. Use ListMessage(?)"); - System.exit(2); - } - } catch (JMSException e) { - e.printStackTrace(); + + /** + * Returns whether the list of Strings is empty. + * + * @param values list to be checked for emptiness + * @return true if the list is empty, false otherwise + */ + private static boolean isEmptyMessage(List values) { + return (values.size() == 1 + && (values.get(0).equals("") || values.get(0).equals("\"\"") || values.get(0).equals("\'\'"))); } - } - - /** - * Fill MapMessage with a data provided by user input as *content*. - * - * @param senderOptions sender options - * @param mapMessage message to be filled with data - */ - private void fillMapMessage(ClientOptions senderOptions, MapMessage mapMessage) { - for (Content c : content) { - LOG.trace("Filling MapMessage with: " + c.getValue() + " class=" + c.getType().getName()); - if (Utils.CLASSES.contains(c.getType())) { + + /** + * Fill object message with data. + * + * @param senderOptions + * @param objectMessage + */ + private void fillObjectMessage(ClientOptions senderOptions, ObjectMessage objectMessage) { try { - switch (c.getType().getSimpleName()) { - case "Integer": - mapMessage.setInt(c.getKey(), (Integer) c.getValue()); - break; - case "Long": - mapMessage.setLong(c.getKey(), (Long) c.getValue()); - break; - case "Float": - mapMessage.setFloat(c.getKey(), (Float) c.getValue()); - break; - case "Double": - mapMessage.setDouble(c.getKey(), (Double) c.getValue()); - break; - case "Boolean": - mapMessage.setBoolean(c.getKey(), (Boolean) c.getValue()); - break; - case "String": - mapMessage.setString(c.getKey(), (String) c.getValue()); - break; - default: - LOG.error("Sending unknown type element!"); - mapMessage.setObject(c.getKey(), c.getValue()); - } - mapMessage.setObject(c.getKey(), c.getValue()); + LOG.debug("Filling object data"); + if (content.size() == 1) { + objectMessage.setObject((Serializable) content.get(0).getValue()); + } else { + LOG.error("Content is bigger then one object. " + + "Don't know how to set for object message multiple data. Use ListMessage(?)"); + System.exit(2); + } } catch (JMSException e) { - LOG.error("Error while setting MapMessage property\n" + e.getMessage()); - e.printStackTrace(); - System.exit(1); + e.printStackTrace(); } - } else { - LOG.error("Unknown data type in message Content. Do not know how to send it. Type=" + c.getType()); - } } - } - - /** - * Write bytes to BytesMessage - * @param senderOptions - * @param bytesMessage - */ - private void fillBytesMessage(ClientOptions senderOptions, BytesMessage bytesMessage) { - LOG.debug("Filling ByteMessage with binary data"); - try { - bytesMessage.writeBytes(binaryMessageData); - } catch (JMSException e) { - e.printStackTrace(); - } - } - - /** - * Set various JMS (header) properties for this message. - * - * @param message to set properties for - * @return same message with updated properties - */ - private Message setMessageProperties(Message message) { - try { - // Set message ID if provided or use default one - if (senderOptions.getOption(ClientOptions.MSG_ID).hasParsedValue()) { - message.setJMSMessageID(senderOptions.getOption(ClientOptions.MSG_ID).getValue()); - } - // Set message Correlation ID - if (senderOptions.getOption(ClientOptions.MSG_CORRELATION_ID).hasParsedValue()) { - message.setJMSCorrelationID(senderOptions.getOption(ClientOptions.MSG_CORRELATION_ID).getValue()); - } - - // Set message Subject - if (senderOptions.getOption(ClientOptions.MSG_SUBJECT).hasParsedValue()) { - message.setJMSType(senderOptions.getOption(ClientOptions.MSG_SUBJECT).getValue()); - } - // Set message reply to destination (queue only for now) - if (senderOptions.getOption(ClientOptions.MSG_REPLY_TO).hasParsedValue()) { - // TODO only queue is implemented for now - how to distinguish topic X queue? prefix topic:// - Destination destination = this.getSessions().get(0) - .createQueue(senderOptions.getOption(ClientOptions.MSG_REPLY_TO).getValue()); - message.setJMSReplyTo(destination); - } - - // Set message type to message content type (some JMS vendors use this internally) - if (senderOptions.getOption(ClientOptions.MSG_CONTENT_TYPE).hasParsedValue()) { - message.setStringProperty("JMS_AMQP_CONTENT_TYPE", senderOptions.getOption(ClientOptions.MSG_CONTENT_TYPE).getValue()); - } - // Set message priority (4 by default) - if (senderOptions.getOption(ClientOptions.MSG_PRIORITY).hasParsedValue()) { - message.setJMSPriority(Integer.parseInt(senderOptions.getOption(ClientOptions.MSG_PRIORITY).getValue())); - } - - // Set the group the message belongs to - if (senderOptions.getOption(ClientOptions.MSG_GROUP_ID).hasParsedValue()) { - message.setStringProperty("JMSXGroupID", senderOptions.getOption(ClientOptions.MSG_GROUP_ID).getValue()); - } - // Set relative position of this message within its group - if (senderOptions.getOption(ClientOptions.MSG_GROUP_SEQ).hasParsedValue()) { - message.setStringProperty("JMSXGroupSeq", senderOptions.getOption(ClientOptions.MSG_GROUP_SEQ).getValue()); - } - - // JMS AMQP specific reply-to-group-id mapping - if (senderOptions.getOption(ClientOptions.MSG_REPLY_TO_GROUP_ID).hasParsedValue()) { - message.setStringProperty("JMS_AMQP_REPLY_TO_GROUP_ID", senderOptions.getOption(ClientOptions.MSG_REPLY_TO_GROUP_ID).getValue()); - } - - } catch (JMSException e) { - e.printStackTrace(); + + /** + * Fill MapMessage with a data provided by user input as *content*. + * + * @param senderOptions sender options + * @param mapMessage message to be filled with data + */ + private void fillMapMessage(ClientOptions senderOptions, MapMessage mapMessage) { + for (Content c : content) { + LOG.trace("Filling MapMessage with: " + c.getValue() + " class=" + c.getType().getName()); + if (Utils.CLASSES.contains(c.getType())) { + try { + switch (c.getType().getSimpleName()) { + case "Integer": + mapMessage.setInt(c.getKey(), (Integer) c.getValue()); + break; + case "Long": + mapMessage.setLong(c.getKey(), (Long) c.getValue()); + break; + case "Float": + mapMessage.setFloat(c.getKey(), (Float) c.getValue()); + break; + case "Double": + mapMessage.setDouble(c.getKey(), (Double) c.getValue()); + break; + case "Boolean": + mapMessage.setBoolean(c.getKey(), (Boolean) c.getValue()); + break; + case "String": + mapMessage.setString(c.getKey(), (String) c.getValue()); + break; + default: + LOG.error("Sending unknown type element!"); + mapMessage.setObject(c.getKey(), c.getValue()); + } + mapMessage.setObject(c.getKey(), c.getValue()); + } catch (JMSException e) { + LOG.error("Error while setting MapMessage property\n" + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } else { + LOG.error("Unknown data type in message Content. Do not know how to send it. Type=" + c.getType()); + } + } } - return message; - } - - /** - * Set custom property values in the JMS header/body. - * Setting is done using reflection on Message object and invoking - * appropriate setXProperty(String, ). - * - * @param message message to have properties updated - */ - private void setCustomMessageProperties(Message message) { - String globalPropertyType = null; - if (senderOptions.getOption(ClientOptions.PROPERTY_TYPE).hasParsedValue()) { - globalPropertyType = senderOptions.getOption(ClientOptions.PROPERTY_TYPE).getValue(); + + /** + * Write bytes to BytesMessage + * + * @param senderOptions + * @param bytesMessage + */ + private void fillBytesMessage(ClientOptions senderOptions, BytesMessage bytesMessage) { + LOG.debug("Filling ByteMessage with binary data"); + try { + bytesMessage.writeBytes(binaryMessageData); + } catch (JMSException e) { + e.printStackTrace(); + } } - if (senderOptions.getOption(ClientOptions.MSG_PROPERTY).hasParsedValue()) { - List customProperties = senderOptions.getOption(ClientOptions.MSG_PROPERTY).getParsedValuesList(); - for (String property : customProperties) { - // Create new 'content' object for property key=value mapping. It is same as Message Content Map, so we can safely reuse - Content propertyContent = new Content(globalPropertyType, property, true); + + /** + * Set various JMS (header) properties for this message. + * + * @param message to set properties for + * @return same message with updated properties + */ + private Message setMessageProperties(Message message) { try { - String simpleName = propertyContent.getType().getSimpleName(); - if (simpleName.equals("Integer")) { - simpleName = "Int"; - } - // Call the appropriate setXProperty(String, ) - complicated with primitive types.. - LOG.trace("calling method \"set" + simpleName + "Property()\" for " + property); - Method messageSetXPropertyMethod = Message.class.getMethod("set" + simpleName + "Property", - String.class, Utils.getPrimitiveClass(propertyContent.getType())); - messageSetXPropertyMethod.invoke(message, propertyContent.getKey(), propertyContent.getValue()); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - LOG.error("Unable to set message property from provided input. Exiting."); - e.printStackTrace(); - System.exit(2); + // Set message ID if provided or use default one + if (senderOptions.getOption(ClientOptions.MSG_ID).hasParsedValue()) { + message.setJMSMessageID(senderOptions.getOption(ClientOptions.MSG_ID).getValue()); + } + // Set message Correlation ID + if (senderOptions.getOption(ClientOptions.MSG_CORRELATION_ID).hasParsedValue()) { + message.setJMSCorrelationID(senderOptions.getOption(ClientOptions.MSG_CORRELATION_ID).getValue()); + } + + // Set message Subject + if (senderOptions.getOption(ClientOptions.MSG_SUBJECT).hasParsedValue()) { + message.setJMSType(senderOptions.getOption(ClientOptions.MSG_SUBJECT).getValue()); + } + // Set message reply to destination (queue only for now) + if (senderOptions.getOption(ClientOptions.MSG_REPLY_TO).hasParsedValue()) { + // TODO only queue is implemented for now - how to distinguish topic X queue? prefix topic:// + Destination destination = this.getSessions().get(0) + .createQueue(senderOptions.getOption(ClientOptions.MSG_REPLY_TO).getValue()); + message.setJMSReplyTo(destination); + } + + // Set message type to message content type (some JMS vendors use this internally) + if (senderOptions.getOption(ClientOptions.MSG_CONTENT_TYPE).hasParsedValue()) { + message.setStringProperty("JMS_AMQP_CONTENT_TYPE", senderOptions.getOption(ClientOptions.MSG_CONTENT_TYPE).getValue()); + } + // Set message priority (4 by default) + if (senderOptions.getOption(ClientOptions.MSG_PRIORITY).hasParsedValue()) { + message.setJMSPriority(Integer.parseInt(senderOptions.getOption(ClientOptions.MSG_PRIORITY).getValue())); + } + + // Set the group the message belongs to + if (senderOptions.getOption(ClientOptions.MSG_GROUP_ID).hasParsedValue()) { + message.setStringProperty("JMSXGroupID", senderOptions.getOption(ClientOptions.MSG_GROUP_ID).getValue()); + } + // Set relative position of this message within its group + if (senderOptions.getOption(ClientOptions.MSG_GROUP_SEQ).hasParsedValue()) { + message.setStringProperty("JMSXGroupSeq", senderOptions.getOption(ClientOptions.MSG_GROUP_SEQ).getValue()); + } + + // JMS AMQP specific reply-to-group-id mapping + if (senderOptions.getOption(ClientOptions.MSG_REPLY_TO_GROUP_ID).hasParsedValue()) { + message.setStringProperty("JMS_AMQP_REPLY_TO_GROUP_ID", senderOptions.getOption(ClientOptions.MSG_REPLY_TO_GROUP_ID).getValue()); + } + + } catch (JMSException e) { + e.printStackTrace(); } - } + return message; } - } - - - public List getContent() { - return content; - } - - @Override - ClientOptions getClientOptions() { - return senderOptions; - } - - - /** - * Create message Content based on provided input. - * This method does not care about types. Creation of object Content - * takes care of autotype-casting and setting the proper values. - * - * @param senderOptions use provided input option - * @return list of created options with at least one value - */ - static void createMessageContent(ClientOptions senderOptions) { - List contentList = new ArrayList<>(); - String globalContentType = null; - // Set global content value - if (senderOptions.getOption(ClientOptions.CONTENT_TYPE).hasParsedValue()) { - globalContentType = senderOptions.getOption(ClientOptions.CONTENT_TYPE).getValue().toLowerCase(); + + /** + * Set custom property values in the JMS header/body. + * Setting is done using reflection on Message object and invoking + * appropriate setXProperty(String, ). + * + * @param message message to have properties updated + */ + private void setCustomMessageProperties(Message message) { + String globalPropertyType = null; + if (senderOptions.getOption(ClientOptions.PROPERTY_TYPE).hasParsedValue()) { + globalPropertyType = senderOptions.getOption(ClientOptions.PROPERTY_TYPE).getValue(); + } + if (senderOptions.getOption(ClientOptions.MSG_PROPERTY).hasParsedValue()) { + List customProperties = senderOptions.getOption(ClientOptions.MSG_PROPERTY).getParsedValuesList(); + for (String property : customProperties) { + // Create new 'content' object for property key=value mapping. It is same as Message Content Map, so we can safely reuse + Content propertyContent = new Content(globalPropertyType, property, true); + try { + String simpleName = propertyContent.getType().getSimpleName(); + if (simpleName.equals("Integer")) { + simpleName = "Int"; + } + // Call the appropriate setXProperty(String, ) - complicated with primitive types.. + LOG.trace("calling method \"set" + simpleName + "Property()\" for " + property); + Method messageSetXPropertyMethod = Message.class.getMethod("set" + simpleName + "Property", + String.class, Utils.getPrimitiveClass(propertyContent.getType())); + messageSetXPropertyMethod.invoke(message, propertyContent.getKey(), propertyContent.getValue()); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + LOG.error("Unable to set message property from provided input. Exiting."); + e.printStackTrace(); + System.exit(2); + } + } + } + } + + + public List getContent() { + return content; } - // Set content stuff - if (senderOptions.getOption(ClientOptions.MSG_CONTENT).hasParsedValue()) { - LOG.trace("set MSG_CONTENT"); - String value = senderOptions.getOption(ClientOptions.MSG_CONTENT).getValue(); - contentList.add(new Content(globalContentType, value, false)); - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { - LOG.trace("set MSG_CONTENT_LIST_ITEM"); - List values = senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).getParsedValuesList(); - for (String parsedItem : values) { - contentList.add(new Content(globalContentType, parsedItem, false)); - } - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { - LOG.trace("set MSG_CONTENT_MAP_ITEM"); - List values = senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).getParsedValuesList(); - for (String parsedItem : values) { - contentList.add(new Content(globalContentType, parsedItem, true)); - } - } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).hasParsedValue()) { - LOG.trace("set MSG_CONTENT_FROM_FILE"); - if (senderOptions.getOption(ClientOptions.MSG_CONTENT_BINARY).hasParsedValue() - && Boolean.parseBoolean(senderOptions.getOption(ClientOptions.MSG_CONTENT_BINARY).getValue())) { - binaryMessageData = readBinaryContentFromFile(senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).getValue()); - } else { - String text = readContentFromFile(senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).getValue()); - contentList.add(new Content(globalContentType, text, false)); - } + + @Override + ClientOptions getClientOptions() { + return senderOptions; } - content = contentList; - } - - - /** - * Read binary content from file - * @param binaryFileName binary file to be read from - * @return read Byte array from file - */ - private static byte[] readBinaryContentFromFile(String binaryFileName) { - File binaryFile = new File(binaryFileName); - byte[] bytesOut = null; - if (binaryFile.canRead()) { - bytesOut = new byte[(int) binaryFile.length()]; - try { - try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(binaryFile))) { - int totalBytesRead = 0; - while (totalBytesRead < bytesOut.length) { - int bytesRemaining = bytesOut.length - totalBytesRead; - //input.read() returns -1, 0, or more : - int bytesRead = bis.read(bytesOut, totalBytesRead, bytesRemaining); - if (bytesRead > 0) { - totalBytesRead = totalBytesRead + bytesRead; + + + /** + * Create message Content based on provided input. + * This method does not care about types. Creation of object Content + * takes care of autotype-casting and setting the proper values. + * + * @param senderOptions use provided input option + * @return list of created options with at least one value + */ + static void createMessageContent(ClientOptions senderOptions) { + List contentList = new ArrayList<>(); + String globalContentType = null; + // Set global content value + if (senderOptions.getOption(ClientOptions.CONTENT_TYPE).hasParsedValue()) { + globalContentType = senderOptions.getOption(ClientOptions.CONTENT_TYPE).getValue().toLowerCase(); + } + // Set content stuff + if (senderOptions.getOption(ClientOptions.MSG_CONTENT).hasParsedValue()) { + LOG.trace("set MSG_CONTENT"); + String value = senderOptions.getOption(ClientOptions.MSG_CONTENT).getValue(); + contentList.add(new Content(globalContentType, value, false)); + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).hasParsedValue()) { + LOG.trace("set MSG_CONTENT_LIST_ITEM"); + List values = senderOptions.getOption(ClientOptions.MSG_CONTENT_LIST_ITEM).getParsedValuesList(); + for (String parsedItem : values) { + contentList.add(new Content(globalContentType, parsedItem, false)); + } + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).hasParsedValue()) { + LOG.trace("set MSG_CONTENT_MAP_ITEM"); + List values = senderOptions.getOption(ClientOptions.MSG_CONTENT_MAP_ITEM).getParsedValuesList(); + for (String parsedItem : values) { + contentList.add(new Content(globalContentType, parsedItem, true)); + } + } else if (senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).hasParsedValue()) { + LOG.trace("set MSG_CONTENT_FROM_FILE"); + if (senderOptions.getOption(ClientOptions.MSG_CONTENT_BINARY).hasParsedValue() + && Boolean.parseBoolean(senderOptions.getOption(ClientOptions.MSG_CONTENT_BINARY).getValue())) { + binaryMessageData = readBinaryContentFromFile(senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).getValue()); + } else { + String text = readContentFromFile(senderOptions.getOption(ClientOptions.MSG_CONTENT_FROM_FILE).getValue()); + contentList.add(new Content(globalContentType, text, false)); } - } } - } catch (IOException e) { - e.printStackTrace(); - } - } else { - LOG.error("Unable to access file " + binaryFileName); - System.exit(2); + content = contentList; } - LOG.debug("ToSend=" + new String(bytesOut)); - return bytesOut; - } - - /** - * Read content from provided file path. File content is returned - * as a string representation of all lines. - * - * @param path path to file to read input from - * @return the concatenad - */ - private static String readContentFromFile(String path) { - StringBuilder fileContent = new StringBuilder(); - try { - Path filePath = Paths.get(path); - if (Files.exists(filePath) && Files.isReadable(filePath)) { - for (String line : Files.readAllLines(filePath, Charset.defaultCharset())) { - fileContent.append(line).append(System.lineSeparator()); + + + /** + * Read binary content from file + * + * @param binaryFileName binary file to be read from + * @return read Byte array from file + */ + private static byte[] readBinaryContentFromFile(String binaryFileName) { + File binaryFile = new File(binaryFileName); + byte[] bytesOut = null; + if (binaryFile.canRead()) { + bytesOut = new byte[(int) binaryFile.length()]; + try { + try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(binaryFile))) { + int totalBytesRead = 0; + while (totalBytesRead < bytesOut.length) { + int bytesRemaining = bytesOut.length - totalBytesRead; + //input.read() returns -1, 0, or more : + int bytesRead = bis.read(bytesOut, totalBytesRead, bytesRemaining); + if (bytesRead > 0) { + totalBytesRead = totalBytesRead + bytesRead; + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } else { + LOG.error("Unable to access file " + binaryFileName); + System.exit(2); + } + LOG.debug("ToSend=" + new String(bytesOut)); + return bytesOut; + } + + /** + * Read content from provided file path. File content is returned + * as a string representation of all lines. + * + * @param path path to file to read input from + * @return the concatenad + */ + private static String readContentFromFile(String path) { + StringBuilder fileContent = new StringBuilder(); + try { + Path filePath = Paths.get(path); + if (Files.exists(filePath) && Files.isReadable(filePath)) { + for (String line : Files.readAllLines(filePath, Charset.defaultCharset())) { + fileContent.append(line).append(System.lineSeparator()); + } + // TODO find better solution for files with new lines - not to append line separators + fileContent.setLength(fileContent.length() - 1); + } else { + LOG.error("Unable to read file from provided path: " + path); + System.exit(2); + } + } catch (IOException ex) { + LOG.error("Cannot read content file \"" + path + "\""); + ex.printStackTrace(); + System.exit(2); } - // TODO find better solution for files with new lines - not to append line separators - fileContent.setLength(fileContent.length() - 1); - } else { - LOG.error("Unable to read file from provided path: " + path); - System.exit(2); - } - } catch (IOException ex) { - LOG.error("Cannot read content file \"" + path + "\""); - ex.printStackTrace(); - System.exit(2); + return fileContent.toString(); } - return fileContent.toString(); - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderOptions.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderOptions.java index 758b7692..c46fb282 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderOptions.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/SenderOptions.java @@ -31,108 +31,108 @@ */ public class SenderOptions extends ClientOptions { - private List options = new LinkedList(); - private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); - private final List senderDefaultOptions = new LinkedList(); + private List options = new LinkedList(); + private Logger LOG = LoggerFactory.getLogger(ReceiverOptions.class); + private final List senderDefaultOptions = new LinkedList(); - { - senderDefaultOptions.addAll(Arrays.asList( - new com.redhat.mqe.lib.Option(ADDRESS, "a", "ADDRESS", "", "Queue/Topic destination"), - new com.redhat.mqe.lib.Option(TIMEOUT, "t", "TIMEOUT", "0", "timeout in seconds to wait before exiting. Use -1 to wait forever."), - new com.redhat.mqe.lib.Option(COUNT, "c", "MESSAGES", "1", "stop after count messages have been sent, zero disables"), - new com.redhat.mqe.lib.Option(DURATION, "d", "DURATION", "0", "message actions total duration in seconds (defines msg-rate together with count)"), - new com.redhat.mqe.lib.Option(DURATION_MODE, "", "VALUE", "after-send", "specifies where to wait (before-send/after-send/after-send-tx-action"), - new com.redhat.mqe.lib.Option(MSG_ID, "i", "MSG_ID", "", "use the supplied id instead of generating one. use \'noid\' to not generate IDs"), - new com.redhat.mqe.lib.Option(PROPERTY_TYPE, "", "PTYPE", "String", "specify the type of message property"), - new com.redhat.mqe.lib.Option(MSG_PROPERTY, "", "KEY=PVALUE", "", "specify message property as KEY=VALUE (use '~' instead of '=' for auto-casting)"), - new com.redhat.mqe.lib.Option(CONTENT_TYPE, "", "CTYPE", "String", "specify type of the actual content type"), - new com.redhat.mqe.lib.Option(MSG_CONTENT_TYPE, "", "MSGTYPE", "", "type of message body to use in header (JMSType)"), - new com.redhat.mqe.lib.Option(MSG_CONTENT_FROM_FILE, "", "PATH", "", "specify filename to load content from"), - new com.redhat.mqe.lib.Option(MSG_CONTENT, "", "CONTENT", "", "actual content fed to message body"), - new com.redhat.mqe.lib.Option(MSG_CONTENT_BINARY, "false", "BIN_CONTENT", "", "is message content binary"), - new com.redhat.mqe.lib.Option(MSG_CONTENT_LIST_ITEM, "L", "VALUE", "", "item from list"), - new com.redhat.mqe.lib.Option(MSG_CONTENT_MAP_ITEM, "M", "KEY=VALUE", "", "Map item specified as KEY=VALUE (use '~' instead of '=' for auto-casting)"), - new com.redhat.mqe.lib.Option(MSG_NOTIMESTAMP, "", "TIMESTAMP", "false", "producer do not create timestamps for messages"), - new com.redhat.mqe.lib.Option(MSG_REPLY_TO, "", "QUEUE", "", "reply to provided queue"), - new com.redhat.mqe.lib.Option(MSG_SUBJECT, "", "SUBJECT", "", "specify message subject"), - new com.redhat.mqe.lib.Option(MSG_DURABLE, "", "MSG_DURABLE", "yes", "send durable messages: yes/no|true/false"), - new com.redhat.mqe.lib.Option(LOG_MSGS, "", "LOGMSGFMT", "upstream", "message[s] reporting style (dict|body|upstream|none)"), - new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "upstream", "report various statistic/debug information"), - new com.redhat.mqe.lib.Option(MSG_TTL, "", "TTL", "0", "message time-to-live (ms)"), - new com.redhat.mqe.lib.Option(MSG_PRIORITY, "", "MSG_PRIORITY", "4", "message priority"), - new com.redhat.mqe.lib.Option(MSG_CORRELATION_ID, "", "MSGCORRID", "", "message correlation id"), - new com.redhat.mqe.lib.Option(MSG_USER_ID, "", "USER", "", "obsolete! use '" + CON_POPULATE_JMSXUSERID + "'"), - new com.redhat.mqe.lib.Option(MSG_GROUP_ID, "", "GROUPID", "", "message group id - JMSXGroupID"), - new com.redhat.mqe.lib.Option(MSG_GROUP_SEQ, "", "SEQUENCE", "", "message group sequence - JMSXGroupSeq"), - new com.redhat.mqe.lib.Option(MSG_REPLY_TO_GROUP_ID, "", "GROUPID", "", "reply to message group id"), - new com.redhat.mqe.lib.Option(TX_SIZE, "", "TXSIZE", "0", "transactional mode: batch message count size"), - new com.redhat.mqe.lib.Option(TX_ACTION, "", "TXACTION", "commit", "transactional action at the end of tx batch (commit|rollback|recover|None)"), - new com.redhat.mqe.lib.Option(TX_ENDLOOP_ACTION, "", "TXACTION", "None", "transactional action after sending all messages in loop (commit|rollback|recover|None)"), - // TODO - new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SYNCMODE", "action", "synchronization mode: none/session/action/persistent/transient"), - new com.redhat.mqe.lib.Option(CAPACITY, "", "CAPACITY", "-1", "sender|receiver capacity (no effect in jms atm)") - )); - } + { + senderDefaultOptions.addAll(Arrays.asList( + new com.redhat.mqe.lib.Option(ADDRESS, "a", "ADDRESS", "", "Queue/Topic destination"), + new com.redhat.mqe.lib.Option(TIMEOUT, "t", "TIMEOUT", "0", "timeout in seconds to wait before exiting. Use -1 to wait forever."), + new com.redhat.mqe.lib.Option(COUNT, "c", "MESSAGES", "1", "stop after count messages have been sent, zero disables"), + new com.redhat.mqe.lib.Option(DURATION, "d", "DURATION", "0", "message actions total duration in seconds (defines msg-rate together with count)"), + new com.redhat.mqe.lib.Option(DURATION_MODE, "", "VALUE", "after-send", "specifies where to wait (before-send/after-send/after-send-tx-action"), + new com.redhat.mqe.lib.Option(MSG_ID, "i", "MSG_ID", "", "use the supplied id instead of generating one. use \'noid\' to not generate IDs"), + new com.redhat.mqe.lib.Option(PROPERTY_TYPE, "", "PTYPE", "String", "specify the type of message property"), + new com.redhat.mqe.lib.Option(MSG_PROPERTY, "", "KEY=PVALUE", "", "specify message property as KEY=VALUE (use '~' instead of '=' for auto-casting)"), + new com.redhat.mqe.lib.Option(CONTENT_TYPE, "", "CTYPE", "String", "specify type of the actual content type"), + new com.redhat.mqe.lib.Option(MSG_CONTENT_TYPE, "", "MSGTYPE", "", "type of message body to use in header (JMSType)"), + new com.redhat.mqe.lib.Option(MSG_CONTENT_FROM_FILE, "", "PATH", "", "specify filename to load content from"), + new com.redhat.mqe.lib.Option(MSG_CONTENT, "", "CONTENT", "", "actual content fed to message body"), + new com.redhat.mqe.lib.Option(MSG_CONTENT_BINARY, "false", "BIN_CONTENT", "", "is message content binary"), + new com.redhat.mqe.lib.Option(MSG_CONTENT_LIST_ITEM, "L", "VALUE", "", "item from list"), + new com.redhat.mqe.lib.Option(MSG_CONTENT_MAP_ITEM, "M", "KEY=VALUE", "", "Map item specified as KEY=VALUE (use '~' instead of '=' for auto-casting)"), + new com.redhat.mqe.lib.Option(MSG_NOTIMESTAMP, "", "TIMESTAMP", "false", "producer do not create timestamps for messages"), + new com.redhat.mqe.lib.Option(MSG_REPLY_TO, "", "QUEUE", "", "reply to provided queue"), + new com.redhat.mqe.lib.Option(MSG_SUBJECT, "", "SUBJECT", "", "specify message subject"), + new com.redhat.mqe.lib.Option(MSG_DURABLE, "", "MSG_DURABLE", "yes", "send durable messages: yes/no|true/false"), + new com.redhat.mqe.lib.Option(LOG_MSGS, "", "LOGMSGFMT", "upstream", "message[s] reporting style (dict|body|upstream|none)"), + new com.redhat.mqe.lib.Option(LOG_STATS, "", "LEVEL", "upstream", "report various statistic/debug information"), + new com.redhat.mqe.lib.Option(MSG_TTL, "", "TTL", "0", "message time-to-live (ms)"), + new com.redhat.mqe.lib.Option(MSG_PRIORITY, "", "MSG_PRIORITY", "4", "message priority"), + new com.redhat.mqe.lib.Option(MSG_CORRELATION_ID, "", "MSGCORRID", "", "message correlation id"), + new com.redhat.mqe.lib.Option(MSG_USER_ID, "", "USER", "", "obsolete! use '" + CON_POPULATE_JMSXUSERID + "'"), + new com.redhat.mqe.lib.Option(MSG_GROUP_ID, "", "GROUPID", "", "message group id - JMSXGroupID"), + new com.redhat.mqe.lib.Option(MSG_GROUP_SEQ, "", "SEQUENCE", "", "message group sequence - JMSXGroupSeq"), + new com.redhat.mqe.lib.Option(MSG_REPLY_TO_GROUP_ID, "", "GROUPID", "", "reply to message group id"), + new com.redhat.mqe.lib.Option(TX_SIZE, "", "TXSIZE", "0", "transactional mode: batch message count size"), + new com.redhat.mqe.lib.Option(TX_ACTION, "", "TXACTION", "commit", "transactional action at the end of tx batch (commit|rollback|recover|None)"), + new com.redhat.mqe.lib.Option(TX_ENDLOOP_ACTION, "", "TXACTION", "None", "transactional action after sending all messages in loop (commit|rollback|recover|None)"), + // TODO + new com.redhat.mqe.lib.Option(SYNC_MODE, "", "SYNCMODE", "action", "synchronization mode: none/session/action/persistent/transient"), + new com.redhat.mqe.lib.Option(CAPACITY, "", "CAPACITY", "-1", "sender|receiver capacity (no effect in jms atm)") + )); + } - public SenderOptions() { - this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), senderDefaultOptions); - } + public SenderOptions() { + this.options = ClientOptionManager.mergeOptionLists(super.getDefaultOptions(), senderDefaultOptions); + } - @Override - public com.redhat.mqe.lib.Option getOption(String name) { - if (name != null) { - for (com.redhat.mqe.lib.Option option : options) { - if (name.equals(option.getName())) - return option; - } - } else { - LOG.error("Accessing client options map with null key."); - throw new IllegalArgumentException("Null name is not allowed!"); + @Override + public com.redhat.mqe.lib.Option getOption(String name) { + if (name != null) { + for (com.redhat.mqe.lib.Option option : options) { + if (name.equals(option.getName())) + return option; + } + } else { + LOG.error("Accessing client options map with null key."); + throw new IllegalArgumentException("Null name is not allowed!"); + } + // TODO fix this!? + return null; } - // TODO fix this!? - return null; - } - @Override - public List getClientDefaultOptions() { - return senderDefaultOptions; - } + @Override + public List getClientDefaultOptions() { + return senderDefaultOptions; + } - public List getClientOptions() { - return options; - } + public List getClientOptions() { + return options; + } - @Override - public String toString() { - return "SenderOptions{" + - "options=" + options + - '}'; - } + @Override + public String toString() { + return "SenderOptions{" + + "options=" + options + + '}'; + } - /** - -h, --help show this help message and exit - -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) - -t TIMEOUT, --timeout TIMEOUT timeout in seconds to wait before exiting (default 0) - -c COUNT, --count COUNT stop after count messages have been sent, zero disables (default 1) - -i, --id use the supplied id instead of generating one - --duration DURATION message actions total duration (defines msg-rate together with count) (default 0) - -P NAME=VALUE, --property NAME=VALUE specify message property - -M KEY=VALUE, --map KEY=VALUE specify entry for map content - --content TEXT specify textual content - --content-from-file TEXT specify filename to load content from - --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all - --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI - --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) - --log-msgs LOGMSGFMT message[s] reporting style (dict|body|upstream|none) (default ) - --log-stats LEVEL report various statistic/debug information (default ) - --tx-batch-size TXBSIZE transactional mode: batch message count size (negative skips tx-action before exit) (default 0) - --tx-action TXACTION transactional action at the end of tx batch (default commit) - --sync-mode SMODE synchronization mode: none/session/action/persistent/transient (default action) + /** + -h, --help show this help message and exit + -b USER/PASS@HOST:PORT, --broker USER/PASS@HOST:PORT connect to specified broker (default guest/guest@localhost:5672) + -t TIMEOUT, --timeout TIMEOUT timeout in seconds to wait before exiting (default 0) + -c COUNT, --count COUNT stop after count messages have been sent, zero disables (default 1) + -i, --id use the supplied id instead of generating one + --duration DURATION message actions total duration (defines msg-rate together with count) (default 0) + -P NAME=VALUE, --property NAME=VALUE specify message property + -M KEY=VALUE, --map KEY=VALUE specify entry for map content + --content TEXT specify textual content + --content-from-file TEXT specify filename to load content from + --con-option NAME=VALUE JMS Connection URL options. Ex sync_ack=true sync_publish=all + --broker-option NAME=VALUE JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI + --connection-options {NAME=VALUE,NAME=VALUE..} QPID Connection URL options. (c++ style) + --log-msgs LOGMSGFMT message[s] reporting style (dict|body|upstream|none) (default ) + --log-stats LEVEL report various statistic/debug information (default ) + --tx-batch-size TXBSIZE transactional mode: batch message count size (negative skips tx-action before exit) (default 0) + --tx-action TXACTION transactional action at the end of tx batch (default commit) + --sync-mode SMODE synchronization mode: none/session/action/persistent/transient (default action) - --durable MSG_DURABLE send durable messages: yes/no (default ) - --ttl TTL message time-to-live (ms) (default 0) - --priority MSG_PRIORITY message time-to-live (ms) (default -1) - --capacity CPCT sender|receiver capacity (no effect in jms atm) (default -1) - --close-sleep CSLEEP sleep before publisher/subscriber/session/connection.close() (default 0) - */ + --durable MSG_DURABLE send durable messages: yes/no (default ) + --ttl TTL message time-to-live (ms) (default 0) + --priority MSG_PRIORITY message time-to-live (ms) (default -1) + --capacity CPCT sender|receiver capacity (no effect in jms atm) (default -1) + --close-sleep CSLEEP sleep before publisher/subscriber/session/connection.close() (default 0) + */ } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_connector.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_connector.java index 6612f169..adb35b8f 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_connector.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_connector.java @@ -24,9 +24,9 @@ */ public class aac1_connector { - public static void main(String[] args) { - CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); - ConnectorClient connectorClient = new ConnectorClient(args); - connectorClient.startClient(); - } + public static void main(String[] args) { + CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); + ConnectorClient connectorClient = new ConnectorClient(args); + connectorClient.startClient(); + } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_receiver.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_receiver.java index 191c4d07..2baabf24 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_receiver.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_receiver.java @@ -21,16 +21,16 @@ public class aac1_receiver { - public static void main(String[] args) { - CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); - ReceiverClient receiverClient = new ReceiverClient(args); - String browsingMode = receiverClient.getClientOptions().getOption(ClientOptions.BROWSER).getValue(); - if (Boolean.parseBoolean(browsingMode)) { - CoreClient.LOG.debug("Browsing mode"); - MessageBrowser msgBrowser = new MessageBrowser(receiverClient.getClientOptions()); - msgBrowser.startClient(); - } else { - receiverClient.startClient(); + public static void main(String[] args) { + CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); + ReceiverClient receiverClient = new ReceiverClient(args); + String browsingMode = receiverClient.getClientOptions().getOption(ClientOptions.BROWSER).getValue(); + if (Boolean.parseBoolean(browsingMode)) { + CoreClient.LOG.debug("Browsing mode"); + MessageBrowser msgBrowser = new MessageBrowser(receiverClient.getClientOptions()); + msgBrowser.startClient(); + } else { + receiverClient.startClient(); + } } - } } diff --git a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_sender.java b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_sender.java index 05dc4a93..daee2435 100644 --- a/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_sender.java +++ b/cli-qpid-jms/src/main/java/com/redhat/mqe/jms/aac1_sender.java @@ -21,9 +21,9 @@ public class aac1_sender { - public static void main(String[] args) { - CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); - SenderClient senderClient = new SenderClient(args); - senderClient.startClient(); - } + public static void main(String[] args) { + CoreClient.setClientType(CoreClient.AMQ_CLIENT_TYPE); + SenderClient senderClient = new SenderClient(args); + senderClient.startClient(); + } } diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/AMQPMessageFormatter.java b/jmslib/src/main/java/com/redhat/mqe/lib/AMQPMessageFormatter.java index cb93c790..4415e807 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/AMQPMessageFormatter.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/AMQPMessageFormatter.java @@ -31,101 +31,101 @@ */ public class AMQPMessageFormatter extends MessageFormatter { - public void printMessageBodyAsText(Message message) { - if (message instanceof TextMessage) { - TextMessage textMessage = (TextMessage) message; - try { - LOG.info(textMessage.getText()); - } catch (JMSException e) { - LOG.error("Unable to retrieve text from message.\n" + e.getMessage()); - e.printStackTrace(); - System.exit(1); - } + public void printMessageBodyAsText(Message message) { + if (message instanceof TextMessage) { + TextMessage textMessage = (TextMessage) message; + try { + LOG.info(textMessage.getText()); + } catch (JMSException e) { + LOG.error("Unable to retrieve text from message.\n" + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } } - } - @SuppressWarnings("unchecked") - public void printMessageAsDict(Message msg) { - StringBuilder msgString = new StringBuilder(); - try { - msgString.append("{"); - // AMQP Header - msgString.append("'durable': ").append(formatBool(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT)); - msgString.append(", 'priority': ").append(formatInt(msg.getJMSPriority())); - msgString.append(", 'ttl': ").append(formatLong(Utils.getTtl(msg))); - msgString.append(", 'first-acquirer': ").append(formatBool(msg.getBooleanProperty(AMQP_FIRST_ACQUIRER))); - msgString.append(", 'delivery-count': ").append(formatInt(substractJMSDeliveryCount(msg.getIntProperty(JMSX_DELIVERY_COUNT)))); - // Delivery Annotations - msgString.append(", 'redelivered': ").append(formatBool(msg.getJMSRedelivered())); + @SuppressWarnings("unchecked") + public void printMessageAsDict(Message msg) { + StringBuilder msgString = new StringBuilder(); + try { + msgString.append("{"); + // AMQP Header + msgString.append("'durable': ").append(formatBool(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT)); + msgString.append(", 'priority': ").append(formatInt(msg.getJMSPriority())); + msgString.append(", 'ttl': ").append(formatLong(Utils.getTtl(msg))); + msgString.append(", 'first-acquirer': ").append(formatBool(msg.getBooleanProperty(AMQP_FIRST_ACQUIRER))); + msgString.append(", 'delivery-count': ").append(formatInt(substractJMSDeliveryCount(msg.getIntProperty(JMSX_DELIVERY_COUNT)))); + // Delivery Annotations + msgString.append(", 'redelivered': ").append(formatBool(msg.getJMSRedelivered())); // JMS2.0 functionality, doesn't work with old clients // msgString.append(", 'delivery-time': ").append(formatLong(msg.getJMSDeliveryTime())); - // AMQP Properties - msgString.append(", 'id': ").append(formatString(msg.getJMSMessageID())); - msgString.append(", 'user_id': ").append(formatString(msg.getStringProperty(JMSX_USER_ID))); - msgString.append(", 'address': ").append(formatAddress(msg.getJMSDestination())); - msgString.append(", 'subject': ").append(formatObject(msg.getJMSType())); - msgString.append(", 'reply_to': ").append(formatAddress(msg.getJMSReplyTo())); - msgString.append(", 'correlation_id': ").append(formatString(msg.getJMSCorrelationID())); - msgString.append(", 'content_type': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_TYPE))); - msgString.append(", 'content_encoding': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_ENCODING))); - msgString.append(", 'absolute-expiry-time': ").append(formatLong(msg.getJMSExpiration())); - msgString.append(", 'creation-time': ").append(formatLong(msg.getJMSTimestamp())); - msgString.append(", 'group-id': ").append(formatString(msg.getStringProperty(JMSX_GROUP_ID))); - msgString.append(", 'group-sequence': ").append(getGroupSequenceNunmber(msg, AMQP_JMSX_GROUP_SEQ)); - msgString.append(", 'reply-to-group-id': ").append(formatString(msg.getStringProperty(AMQP_REPLY_TO_GROUP_ID))); - // Application Properties - msgString.append(", 'properties': ").append(formatProperties(msg)); - // Application Data - msgString.append(", 'content': ").append(formatContent(msg)); // - msgString.append("}"); - } catch (JMSException jmse) { - LOG.error("Error while getting message properties!", jmse.getMessage()); - jmse.printStackTrace(); - System.exit(1); + // AMQP Properties + msgString.append(", 'id': ").append(formatString(msg.getJMSMessageID())); + msgString.append(", 'user_id': ").append(formatString(msg.getStringProperty(JMSX_USER_ID))); + msgString.append(", 'address': ").append(formatAddress(msg.getJMSDestination())); + msgString.append(", 'subject': ").append(formatObject(msg.getJMSType())); + msgString.append(", 'reply_to': ").append(formatAddress(msg.getJMSReplyTo())); + msgString.append(", 'correlation_id': ").append(formatString(msg.getJMSCorrelationID())); + msgString.append(", 'content_type': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_TYPE))); + msgString.append(", 'content_encoding': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_ENCODING))); + msgString.append(", 'absolute-expiry-time': ").append(formatLong(msg.getJMSExpiration())); + msgString.append(", 'creation-time': ").append(formatLong(msg.getJMSTimestamp())); + msgString.append(", 'group-id': ").append(formatString(msg.getStringProperty(JMSX_GROUP_ID))); + msgString.append(", 'group-sequence': ").append(getGroupSequenceNunmber(msg, AMQP_JMSX_GROUP_SEQ)); + msgString.append(", 'reply-to-group-id': ").append(formatString(msg.getStringProperty(AMQP_REPLY_TO_GROUP_ID))); + // Application Properties + msgString.append(", 'properties': ").append(formatProperties(msg)); + // Application Data + msgString.append(", 'content': ").append(formatContent(msg)); // + msgString.append("}"); + } catch (JMSException jmse) { + LOG.error("Error while getting message properties!", jmse.getMessage()); + jmse.printStackTrace(); + System.exit(1); + } + LOG.info(msgString.toString()); } - LOG.info(msgString.toString()); - } - @SuppressWarnings("unchecked") - public void printMessageAsInterop(Message msg) { - StringBuilder msgString = new StringBuilder(); - try { - msgString.append("{"); - // AMQP Header - msgString.append("'durable': ").append(formatBool(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT)); - msgString.append(", 'priority': ").append(formatInt(msg.getJMSPriority())); - msgString.append(", 'ttl': ").append(formatLong(Utils.getTtl(msg))); - msgString.append(", 'first-acquirer': ").append(formatBool(msg.getBooleanProperty(AMQP_FIRST_ACQUIRER))); - msgString.append(", 'delivery-count': ").append(formatInt(substractJMSDeliveryCount(msg.getIntProperty(JMSX_DELIVERY_COUNT)))); - // Delivery Annotations - // JMS specifics + @SuppressWarnings("unchecked") + public void printMessageAsInterop(Message msg) { + StringBuilder msgString = new StringBuilder(); + try { + msgString.append("{"); + // AMQP Header + msgString.append("'durable': ").append(formatBool(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT)); + msgString.append(", 'priority': ").append(formatInt(msg.getJMSPriority())); + msgString.append(", 'ttl': ").append(formatLong(Utils.getTtl(msg))); + msgString.append(", 'first-acquirer': ").append(formatBool(msg.getBooleanProperty(AMQP_FIRST_ACQUIRER))); + msgString.append(", 'delivery-count': ").append(formatInt(substractJMSDeliveryCount(msg.getIntProperty(JMSX_DELIVERY_COUNT)))); + // Delivery Annotations + // JMS specifics // msgString.append(", 'redelivered': ").append(formatBool(msg.getJMSRedelivered())); // msgString.append(", 'delivery-time': ").append(formatLong(msg.getJMSDeliveryTime())); - // AMQP Properties - msgString.append(", 'id': ").append(formatString(removeIDprefix(msg.getJMSMessageID()))); - msgString.append(", 'user-id': ").append(formatString(msg.getStringProperty(JMSX_USER_ID))); - msgString.append(", 'address': ").append(formatAddress(msg.getJMSDestination())); - msgString.append(", 'subject': ").append(formatObject(msg.getJMSType())); - msgString.append(", 'reply-to': ").append(formatAddress(msg.getJMSReplyTo())); - msgString.append(", 'correlation-id': ").append(formatString(removeIDprefix(msg.getJMSCorrelationID()))); - msgString.append(", 'content-type': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_TYPE))); - msgString.append(", 'content-encoding': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_ENCODING))); - msgString.append(", 'absolute-expiry-time': ").append(formatLong(msg.getJMSExpiration())); - msgString.append(", 'creation-time': ").append(formatLong(msg.getJMSTimestamp())); - msgString.append(", 'group-id': ").append(formatString(msg.getStringProperty(JMSX_GROUP_ID))); - msgString.append(", 'group-sequence': ").append(getGroupSequenceNunmber(msg, AMQP_JMSX_GROUP_SEQ)); - msgString.append(", 'reply-to-group-id': ").append(formatString(msg.getStringProperty(AMQP_REPLY_TO_GROUP_ID))); - // Application Properties - msgString.append(", 'properties': ").append(formatProperties(msg)); - // Application Data - msgString.append(", 'content': ").append(formatContent(msg)); // - msgString.append("}"); - } catch (JMSException jmse) { - LOG.error("Error while getting message properties!", jmse.getMessage()); - jmse.printStackTrace(); - System.exit(1); + // AMQP Properties + msgString.append(", 'id': ").append(formatString(removeIDprefix(msg.getJMSMessageID()))); + msgString.append(", 'user-id': ").append(formatString(msg.getStringProperty(JMSX_USER_ID))); + msgString.append(", 'address': ").append(formatAddress(msg.getJMSDestination())); + msgString.append(", 'subject': ").append(formatObject(msg.getJMSType())); + msgString.append(", 'reply-to': ").append(formatAddress(msg.getJMSReplyTo())); + msgString.append(", 'correlation-id': ").append(formatString(removeIDprefix(msg.getJMSCorrelationID()))); + msgString.append(", 'content-type': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_TYPE))); + msgString.append(", 'content-encoding': ").append(formatString(msg.getStringProperty(AMQP_CONTENT_ENCODING))); + msgString.append(", 'absolute-expiry-time': ").append(formatLong(msg.getJMSExpiration())); + msgString.append(", 'creation-time': ").append(formatLong(msg.getJMSTimestamp())); + msgString.append(", 'group-id': ").append(formatString(msg.getStringProperty(JMSX_GROUP_ID))); + msgString.append(", 'group-sequence': ").append(getGroupSequenceNunmber(msg, AMQP_JMSX_GROUP_SEQ)); + msgString.append(", 'reply-to-group-id': ").append(formatString(msg.getStringProperty(AMQP_REPLY_TO_GROUP_ID))); + // Application Properties + msgString.append(", 'properties': ").append(formatProperties(msg)); + // Application Data + msgString.append(", 'content': ").append(formatContent(msg)); // + msgString.append("}"); + } catch (JMSException jmse) { + LOG.error("Error while getting message properties!", jmse.getMessage()); + jmse.printStackTrace(); + System.exit(1); + } + LOG.info(msgString.toString()); } - LOG.info(msgString.toString()); - } } diff --git a/jmslib/src/main/java/com/redhat/mqe/lib/ClientOptionManager.java b/jmslib/src/main/java/com/redhat/mqe/lib/ClientOptionManager.java index b34193c7..02a7700e 100644 --- a/jmslib/src/main/java/com/redhat/mqe/lib/ClientOptionManager.java +++ b/jmslib/src/main/java/com/redhat/mqe/lib/ClientOptionManager.java @@ -36,369 +36,370 @@ * client options list, then accordingly set for client. */ public class ClientOptionManager { - private static final Logger LOG = LoggerFactory.getLogger(ClientOptionManager.class); - /** - * Mapping from cli options to connection factory properties. - * Null value means key should not become connection factory property. - */ - protected final Map CONNECTION_TRANSLATION_MAP = new HashMap<>(); - protected Map connectionOptionsUrlMap = new HashMap<>(); - private List