You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by jb...@apache.org on 2017/05/04 16:05:48 UTC
[1/6] activemq-artemis git commit: ARTEMIS-904 Remove cyclic
dependencies from artemis-cli
Repository: activemq-artemis
Updated Branches:
refs/heads/master eeca06d25 -> b9e7e7ed9
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ProducerThread.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ProducerThread.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ProducerThread.java
deleted file mode 100644
index 67cef67..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ProducerThread.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.util;
-
-import javax.jms.BytesMessage;
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.activemq.artemis.utils.ReusableLatch;
-
-public class ProducerThread extends Thread {
-
- protected final Session session;
-
- boolean verbose;
- int messageCount = 1000;
- boolean runIndefinitely = false;
- Destination destination;
- int sleep = 0;
- boolean persistent = true;
- int messageSize = 0;
- int textMessageSize;
- long msgTTL = 0L;
- String msgGroupID = null;
- int transactionBatchSize;
-
- int transactions = 0;
- final AtomicInteger sentCount = new AtomicInteger(0);
- String message;
- String messageText = null;
- String payloadUrl = null;
- byte[] payload = null;
- boolean running = false;
- final ReusableLatch finished = new ReusableLatch(1);
- final ReusableLatch paused = new ReusableLatch(0);
-
- public ProducerThread(Session session, Destination destination, int threadNr) {
- super("Producer " + destination.toString() + ", thread=" + threadNr);
- this.destination = destination;
- this.session = session;
- }
-
- @Override
- public void run() {
- MessageProducer producer = null;
- String threadName = Thread.currentThread().getName();
- try {
- producer = session.createProducer(destination);
- producer.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
- producer.setTimeToLive(msgTTL);
- initPayLoad();
- running = true;
-
- System.out.println(threadName + " Started to calculate elapsed time ...\n");
- long tStart = System.currentTimeMillis();
-
- if (runIndefinitely) {
- while (running) {
- paused.await();
- sendMessage(producer, threadName);
- sentCount.incrementAndGet();
- }
- } else {
- for (sentCount.set(0); sentCount.get() < messageCount && running; sentCount.incrementAndGet()) {
- paused.await();
- sendMessage(producer, threadName);
- }
- }
-
- try {
- session.commit();
- } catch (Throwable ignored) {
- }
-
- System.out.println(threadName + " Produced: " + this.getSentCount() + " messages");
- long tEnd = System.currentTimeMillis();
- long elapsed = (tEnd - tStart) / 1000;
- System.out.println(threadName + " Elapsed time in second : " + elapsed + " s");
- System.out.println(threadName + " Elapsed time in milli second : " + (tEnd - tStart) + " milli seconds");
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (finished != null) {
- finished.countDown();
- }
- if (producer != null) {
- try {
- producer.close();
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- private void sendMessage(MessageProducer producer, String threadName) throws Exception {
- Message message = createMessage(sentCount.get(), threadName);
- producer.send(message);
- if (verbose) {
- System.out.println(threadName + " Sent: " + (message instanceof TextMessage ? ((TextMessage) message).getText() : message.getJMSMessageID()));
- }
-
- if (transactionBatchSize > 0 && sentCount.get() > 0 && sentCount.get() % transactionBatchSize == 0) {
- System.out.println(threadName + " Committing transaction: " + transactions++);
- session.commit();
- }
-
- if (sleep > 0) {
- Thread.sleep(sleep);
- }
- }
-
- private void initPayLoad() {
- if (messageSize > 0) {
- payload = new byte[messageSize];
- for (int i = 0; i < payload.length; i++) {
- payload[i] = '.';
- }
- }
- }
-
- protected Message createMessage(int i, String threadName) throws Exception {
- Message answer;
- if (payload != null) {
- answer = session.createBytesMessage();
- ((BytesMessage) answer).writeBytes(payload);
- } else {
- if (textMessageSize > 0) {
- if (messageText == null) {
- messageText = readInputStream(getClass().getResourceAsStream("demo.txt"), textMessageSize, i);
- }
- } else if (payloadUrl != null) {
- messageText = readInputStream(new URL(payloadUrl).openStream(), -1, i);
- } else if (message != null) {
- messageText = message;
- } else {
- messageText = createDefaultMessage(i);
- }
- answer = session.createTextMessage(messageText);
- }
- if ((msgGroupID != null) && (!msgGroupID.isEmpty())) {
- answer.setStringProperty("JMSXGroupID", msgGroupID);
- }
-
- answer.setIntProperty("count", i);
- answer.setStringProperty("ThreadSent", threadName);
- return answer;
- }
-
- private String readInputStream(InputStream is, int size, int messageNumber) throws IOException {
- try (InputStreamReader reader = new InputStreamReader(is)) {
- char[] buffer;
- if (size > 0) {
- buffer = new char[size];
- } else {
- buffer = new char[1024];
- }
- int count;
- StringBuilder builder = new StringBuilder();
- while ((count = reader.read(buffer)) != -1) {
- builder.append(buffer, 0, count);
- if (size > 0)
- break;
- }
- return builder.toString();
- } catch (IOException ioe) {
- return createDefaultMessage(messageNumber);
- }
- }
-
- private String createDefaultMessage(int messageNumber) {
- return "test message: " + messageNumber;
- }
-
- public ProducerThread setMessageCount(int messageCount) {
- this.messageCount = messageCount;
- return this;
- }
-
- public int getSleep() {
- return sleep;
- }
-
- public ProducerThread setSleep(int sleep) {
- this.sleep = sleep;
- return this;
- }
-
- public int getMessageCount() {
- return messageCount;
- }
-
- public int getSentCount() {
- return sentCount.get();
- }
-
- public boolean isPersistent() {
- return persistent;
- }
-
- public ProducerThread setPersistent(boolean persistent) {
- this.persistent = persistent;
- return this;
- }
-
- public boolean isRunning() {
- return running;
- }
-
- public ProducerThread setRunning(boolean running) {
- this.running = running;
- return this;
- }
-
- public long getMsgTTL() {
- return msgTTL;
- }
-
- public ProducerThread setMsgTTL(long msgTTL) {
- this.msgTTL = msgTTL;
- return this;
- }
-
- public int getTransactionBatchSize() {
- return transactionBatchSize;
- }
-
- public ProducerThread setTransactionBatchSize(int transactionBatchSize) {
- this.transactionBatchSize = transactionBatchSize;
- return this;
- }
-
- public String getMsgGroupID() {
- return msgGroupID;
- }
-
- public ProducerThread setMsgGroupID(String msgGroupID) {
- this.msgGroupID = msgGroupID;
- return this;
- }
-
- public int getTextMessageSize() {
- return textMessageSize;
- }
-
- public ProducerThread setTextMessageSize(int textMessageSize) {
- this.textMessageSize = textMessageSize;
- return this;
- }
-
- public int getMessageSize() {
- return messageSize;
- }
-
- public ProducerThread setMessageSize(int messageSize) {
- this.messageSize = messageSize;
- return this;
- }
-
- public ReusableLatch getFinished() {
- return finished;
- }
-
- public ProducerThread setFinished(int value) {
- finished.setCount(value);
- return this;
- }
-
- public String getPayloadUrl() {
- return payloadUrl;
- }
-
- public ProducerThread setPayloadUrl(String payloadUrl) {
- this.payloadUrl = payloadUrl;
- return this;
- }
-
- public String getMessage() {
- return message;
- }
-
- public ProducerThread setMessage(String message) {
- this.message = message;
- return this;
- }
-
- public boolean isRunIndefinitely() {
- return runIndefinitely;
- }
-
- public ProducerThread setRunIndefinitely(boolean runIndefinitely) {
- this.runIndefinitely = runIndefinitely;
- return this;
- }
-
- public ProducerThread pauseProducer() {
- this.paused.countUp();
- return this;
- }
-
- public ProducerThread resumeProducer() {
- this.paused.countDown();
- return this;
- }
-
- public ProducerThread resetCounters() {
- this.sentCount.set(0);
- return this;
- }
-
- public boolean isVerbose() {
- return verbose;
- }
-
- public ProducerThread setVerbose(boolean verbose) {
- this.verbose = verbose;
- return this;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactory.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactory.java
new file mode 100644
index 0000000..dc9b9e1
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactory.java
@@ -0,0 +1,73 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.activemq.artemis.cli.ConfigurationException;
+import org.apache.activemq.artemis.dto.BrokerDTO;
+import org.apache.activemq.artemis.dto.ServerDTO;
+import org.apache.activemq.artemis.integration.Broker;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.utils.FactoryFinder;
+
+public class BrokerFactory {
+
+ private static BrokerDTO createBrokerConfiguration(URI configURI,
+ String artemisHome,
+ String artemisInstance,
+ URI artemisURIInstance) throws Exception {
+ if (configURI.getScheme() == null) {
+ throw new ConfigurationException("Invalid configuration URI, no scheme specified: " + configURI);
+ }
+
+ BrokerFactoryHandler factory = null;
+ try {
+ FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/");
+ factory = (BrokerFactoryHandler) finder.newInstance(configURI.getScheme());
+ } catch (IOException ioe) {
+ throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
+ }
+ return factory.createBroker(configURI, artemisHome, artemisInstance, artemisURIInstance);
+ }
+
+ public static BrokerDTO createBrokerConfiguration(String configuration,
+ String artemisHome,
+ String artemisInstance,
+ URI artemisURIInstance) throws Exception {
+ return createBrokerConfiguration(new URI(configuration), artemisHome, artemisInstance, artemisURIInstance);
+ }
+
+ public static Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) throws Exception {
+ if (brokerDTO.configuration != null) {
+ BrokerHandler handler;
+ URI configURI = brokerDTO.getConfigurationURI();
+
+ try {
+ FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/server/");
+ handler = (BrokerHandler) finder.newInstance(configURI.getScheme());
+ } catch (IOException ioe) {
+ throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
+ }
+
+ return handler.createServer(brokerDTO, security);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactoryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactoryHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactoryHandler.java
new file mode 100644
index 0000000..2d16c3a
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerFactoryHandler.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory;
+
+import java.net.URI;
+
+import org.apache.activemq.artemis.dto.BrokerDTO;
+
+public interface BrokerFactoryHandler {
+
+ BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerHandler.java
new file mode 100644
index 0000000..df874a7
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/BrokerHandler.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory;
+
+import org.apache.activemq.artemis.dto.ServerDTO;
+import org.apache.activemq.artemis.integration.Broker;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+
+public interface BrokerHandler {
+
+ Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/FileBrokerHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/FileBrokerHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/FileBrokerHandler.java
new file mode 100644
index 0000000..74d1eb7
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/FileBrokerHandler.java
@@ -0,0 +1,30 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory;
+
+import org.apache.activemq.artemis.dto.ServerDTO;
+import org.apache.activemq.artemis.integration.Broker;
+import org.apache.activemq.artemis.integration.FileBroker;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+
+public class FileBrokerHandler implements BrokerHandler {
+
+ @Override
+ public Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) {
+ return new FileBroker(brokerDTO, security);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/JaasSecurityHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/JaasSecurityHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/JaasSecurityHandler.java
new file mode 100644
index 0000000..a096567
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/JaasSecurityHandler.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory.security;
+
+import org.apache.activemq.artemis.dto.JaasSecurityDTO;
+import org.apache.activemq.artemis.dto.SecurityDTO;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+
+public class JaasSecurityHandler implements SecurityHandler {
+
+ @Override
+ public ActiveMQSecurityManager createSecurityManager(SecurityDTO security) throws Exception {
+ JaasSecurityDTO jaasSecurity = (JaasSecurityDTO) security;
+ return new ActiveMQJAASSecurityManager(jaasSecurity.domain, jaasSecurity.certificateDomain);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityHandler.java
new file mode 100644
index 0000000..df90517
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityHandler.java
@@ -0,0 +1,25 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory.security;
+
+import org.apache.activemq.artemis.dto.SecurityDTO;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+
+public interface SecurityHandler {
+
+ ActiveMQSecurityManager createSecurityManager(SecurityDTO securityDTO) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerFactory.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerFactory.java
new file mode 100644
index 0000000..3ebf8c3
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerFactory.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory.security;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.activemq.artemis.dto.SecurityDTO;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.utils.FactoryFinder;
+
+public class SecurityManagerFactory {
+
+ public static ActiveMQSecurityManager create(SecurityDTO config) throws Exception {
+ if (config == null) {
+ throw new Exception("No security manager configured!");
+ }
+ FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/security/");
+ SecurityHandler securityHandler = (SecurityHandler) finder.newInstance(config.getClass().getAnnotation(XmlRootElement.class).name());
+ return securityHandler.createSecurityManager(config);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/xml/XmlBrokerFactoryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/xml/XmlBrokerFactoryHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/xml/XmlBrokerFactoryHandler.java
new file mode 100644
index 0000000..8284252
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/xml/XmlBrokerFactoryHandler.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.factory.xml;
+
+import java.io.File;
+import java.net.URI;
+
+import org.apache.activemq.artemis.cli.ConfigurationException;
+import org.apache.activemq.artemis.cli.factory.BrokerFactoryHandler;
+import org.apache.activemq.artemis.dto.BrokerDTO;
+import org.apache.activemq.artemis.dto.XmlUtil;
+
+public class XmlBrokerFactoryHandler implements BrokerFactoryHandler {
+
+ @Override
+ public BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception {
+ File file = new File(brokerURI.getSchemeSpecificPart());
+ if (!file.exists()) {
+ throw new ConfigurationException("Invalid configuration URI, can't find file: " + file.getName());
+ }
+ return XmlUtil.decode(BrokerDTO.class, file, artemisHome, artemisInstance, artemisURIInstance);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactory.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactory.java
deleted file mode 100644
index a188c61..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import java.io.IOException;
-import java.net.URI;
-
-import org.apache.activemq.artemis.cli.ConfigurationException;
-import org.apache.activemq.artemis.dto.BrokerDTO;
-import org.apache.activemq.artemis.dto.ServerDTO;
-import org.apache.activemq.artemis.integration.Broker;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-import org.apache.activemq.artemis.utils.FactoryFinder;
-
-public class BrokerFactory {
-
- public static BrokerDTO createBrokerConfiguration(URI configURI) throws Exception {
- return createBrokerConfiguration(configURI, null, null, null);
- }
-
- public static BrokerDTO createBrokerConfiguration(URI configURI,
- String artemisHome,
- String artemisInstance,
- URI artemisURIInstance) throws Exception {
- if (configURI.getScheme() == null) {
- throw new ConfigurationException("Invalid configuration URI, no scheme specified: " + configURI);
- }
-
- BrokerFactoryHandler factory = null;
- try {
- FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/");
- factory = (BrokerFactoryHandler) finder.newInstance(configURI.getScheme());
- } catch (IOException ioe) {
- throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
- }
-
- return factory.createBroker(configURI, artemisHome, artemisInstance, artemisURIInstance);
- }
-
- public static BrokerDTO createBrokerConfiguration(String configuration) throws Exception {
- return createBrokerConfiguration(new URI(configuration), null, null, null);
- }
-
- public static BrokerDTO createBrokerConfiguration(String configuration,
- String artemisHome,
- String artemisInstance,
- URI artemisURIInstance) throws Exception {
- return createBrokerConfiguration(new URI(configuration), artemisHome, artemisInstance, artemisURIInstance);
- }
-
- public static Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) throws Exception {
- if (brokerDTO.configuration != null) {
- BrokerHandler handler;
- URI configURI = brokerDTO.getConfigurationURI();
-
- try {
- FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/server/");
- handler = (BrokerHandler) finder.newInstance(configURI.getScheme());
- } catch (IOException ioe) {
- throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
- }
-
- return handler.createServer(brokerDTO, security);
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactoryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactoryHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactoryHandler.java
deleted file mode 100644
index f81a0de..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerFactoryHandler.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import java.net.URI;
-
-import org.apache.activemq.artemis.dto.BrokerDTO;
-
-public interface BrokerFactoryHandler {
-
- BrokerDTO createBroker(URI brokerURI) throws Exception;
-
- BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerHandler.java
deleted file mode 100644
index 3fe4027..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/BrokerHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import org.apache.activemq.artemis.dto.ServerDTO;
-import org.apache.activemq.artemis.integration.Broker;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-
-public interface BrokerHandler {
-
- Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/FileBrokerHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/FileBrokerHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/FileBrokerHandler.java
deleted file mode 100644
index f6afc7f..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/FileBrokerHandler.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import org.apache.activemq.artemis.dto.ServerDTO;
-import org.apache.activemq.artemis.integration.Broker;
-import org.apache.activemq.artemis.integration.FileBroker;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-
-public class FileBrokerHandler implements BrokerHandler {
-
- @Override
- public Broker createServer(ServerDTO brokerDTO, ActiveMQSecurityManager security) {
- return new FileBroker(brokerDTO, security);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/JaasSecurityHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/JaasSecurityHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/JaasSecurityHandler.java
deleted file mode 100644
index 9f0c489..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/JaasSecurityHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import org.apache.activemq.artemis.dto.JaasSecurityDTO;
-import org.apache.activemq.artemis.dto.SecurityDTO;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-
-public class JaasSecurityHandler implements SecurityHandler {
-
- @Override
- public ActiveMQSecurityManager createSecurityManager(SecurityDTO security) throws Exception {
- JaasSecurityDTO jaasSecurity = (JaasSecurityDTO) security;
- ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager(jaasSecurity.domain, jaasSecurity.certificateDomain);
- return securityManager;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityHandler.java
deleted file mode 100644
index 75768d0..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import org.apache.activemq.artemis.dto.SecurityDTO;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-
-public interface SecurityHandler {
-
- ActiveMQSecurityManager createSecurityManager(SecurityDTO securityDTO) throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityManagerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityManagerFactory.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityManagerFactory.java
deleted file mode 100644
index 4b71029..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/SecurityManagerFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.activemq.artemis.dto.SecurityDTO;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
-import org.apache.activemq.artemis.utils.FactoryFinder;
-
-public class SecurityManagerFactory {
-
- public static ActiveMQSecurityManager create(SecurityDTO config) throws Exception {
- if (config != null) {
- FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/security/");
- SecurityHandler securityHandler = (SecurityHandler) finder.newInstance(config.getClass().getAnnotation(XmlRootElement.class).name());
- return securityHandler.createSecurityManager(config);
- } else {
- throw new Exception("No security manager configured!");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/XmlBrokerFactoryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/XmlBrokerFactoryHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/XmlBrokerFactoryHandler.java
deleted file mode 100644
index 0059c06..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/factory/XmlBrokerFactoryHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.factory;
-
-import java.io.File;
-import java.net.URI;
-
-import org.apache.activemq.artemis.cli.ConfigurationException;
-import org.apache.activemq.artemis.dto.BrokerDTO;
-import org.apache.activemq.artemis.dto.XmlUtil;
-
-public class XmlBrokerFactoryHandler implements BrokerFactoryHandler {
-
- @Override
- public BrokerDTO createBroker(URI brokerURI) throws Exception {
- return createBroker(brokerURI, null, null, null);
- }
-
- @Override
- public BrokerDTO createBroker(URI brokerURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception {
- File file = new File(brokerURI.getSchemeSpecificPart());
- if (!file.exists()) {
- throw new ConfigurationException("Invalid configuration URI, can't find file: " + file.getName());
- }
- return XmlUtil.decode(BrokerDTO.class, file, artemisHome, artemisInstance, artemisURIInstance);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java
index e112644..af2286f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java
@@ -21,13 +21,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.core.config.CoreAddressConfiguration;
import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.core.server.ServiceComponent;
import org.apache.activemq.artemis.dto.ServerDTO;
import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger;
@@ -161,7 +161,7 @@ public class FileBroker implements Broker {
* this makes sure the components are started in the correct order. Its simple at the mo as e only have core and jms but
* will need impproving if we get more.
* */
- public ArrayList<ActiveMQComponent> getComponentsByStartOrder(Map<String, ActiveMQComponent> components) {
+ private ArrayList<ActiveMQComponent> getComponentsByStartOrder(Map<String, ActiveMQComponent> components) {
ArrayList<ActiveMQComponent> activeMQComponents = new ArrayList<>();
ActiveMQComponent jmsComponent = components.get("jms");
if (jmsComponent != null) {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/util/FileBasedSecStoreConfig.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/FileBasedSecStoreConfig.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/FileBasedSecStoreConfig.java
deleted file mode 100644
index c3f30b3..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/FileBasedSecStoreConfig.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.util;
-
-import org.apache.activemq.artemis.api.core.Pair;
-import org.apache.activemq.artemis.utils.StringUtil;
-import org.apache.commons.configuration2.PropertiesConfiguration;
-import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
-import org.apache.commons.configuration2.builder.fluent.Configurations;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-public class FileBasedSecStoreConfig {
-
- private static final String LICENSE_HEADER =
- "## ---------------------------------------------------------------------------\n" +
- "## Licensed to the Apache Software Foundation (ASF) under one or more\n" +
- "## contributor license agreements. See the NOTICE file distributed with\n" +
- "## this work for additional information regarding copyright ownership.\n" +
- "## The ASF licenses this file to You under the Apache License, Version 2.0\n" +
- "## (the \"License\"); you may not use this file except in compliance with\n" +
- "## the License. You may obtain a copy of the License at\n" +
- "##\n" +
- "## http://www.apache.org/licenses/LICENSE-2.0\n" +
- "##\n" +
- "## Unless required by applicable law or agreed to in writing, software\n" +
- "## distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
- "## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
- "## See the License for the specific language governing permissions and\n" +
- "## limitations under the License.\n" +
- "## ---------------------------------------------------------------------------\n";
- private FileBasedConfigurationBuilder<PropertiesConfiguration> userBuilder;
- private FileBasedConfigurationBuilder<PropertiesConfiguration> roleBuilder;
- private PropertiesConfiguration userConfig;
- private PropertiesConfiguration roleConfig;
-
- public FileBasedSecStoreConfig(File userFile, File roleFile) throws Exception {
- Configurations configs = new Configurations();
- userBuilder = configs.propertiesBuilder(userFile);
- roleBuilder = configs.propertiesBuilder(roleFile);
- userConfig = userBuilder.getConfiguration();
- roleConfig = roleBuilder.getConfiguration();
-
- String roleHeader = roleConfig.getLayout().getHeaderComment();
- String userHeader = userConfig.getLayout().getHeaderComment();
-
- if (userHeader == null) {
- if (userConfig.isEmpty()) {
- //clean and reset header
- userConfig.clear();
- userConfig.setHeader(LICENSE_HEADER);
- }
- }
-
- if (roleHeader == null) {
- if (roleConfig.isEmpty()) {
- //clean and reset header
- roleConfig.clear();
- roleConfig.setHeader(LICENSE_HEADER);
- }
- }
- }
-
- public void addNewUser(String username, String hash, String... roles) throws Exception {
- if (userConfig.getString(username) != null) {
- throw new IllegalArgumentException("User already exist: " + username);
- }
- userConfig.addProperty(username, hash);
- addRoles(username, roles);
- }
-
- public void save() throws Exception {
- userBuilder.save();
- roleBuilder.save();
- }
-
- public void removeUser(String username) throws Exception {
- if (userConfig.getProperty(username) == null) {
- throw new IllegalArgumentException("user " + username + " doesn't exist.");
- }
- userConfig.clearProperty(username);
- removeRoles(username);
- }
-
- public List<String> listUser(String username) {
- List<String> result = new ArrayList<>();
- result.add("--- \"user\"(roles) ---\n");
-
- int totalUsers = 0;
- if (username != null) {
- String roles = findRoles(username);
- result.add("\"" + username + "\"(" + roles + ")");
- totalUsers++;
- } else {
- Iterator<String> iter = userConfig.getKeys();
- while (iter.hasNext()) {
- String keyUser = iter.next();
- String roles = findRoles(keyUser);
- result.add("\"" + keyUser + "\"(" + roles + ")");
- totalUsers++;
- }
- }
- result.add("\n Total: " + totalUsers);
- return result;
- }
-
- private String findRoles(String uname) {
- Iterator<String> iter = roleConfig.getKeys();
- StringBuilder builder = new StringBuilder();
- boolean first = true;
- while (iter.hasNext()) {
- String role = iter.next();
- List<String> names = roleConfig.getList(String.class, role);
- for (String value : names) {
- //each value may be a comma separated list
- String[] items = value.split(",");
- for (String item : items) {
- if (item.equals(uname)) {
- if (!first) {
- builder.append(",");
- }
- builder.append(role);
- first = false;
- }
- }
- }
- }
-
- return builder.toString();
- }
-
- public void updateUser(String username, String password, String[] roles) {
- String oldPassword = (String) userConfig.getProperty(username);
- if (oldPassword == null) {
- throw new IllegalArgumentException("user " + username + " doesn't exist.");
- }
-
- if (password != null) {
- userConfig.setProperty(username, password);
- }
-
- if (roles != null && roles.length > 0) {
-
- removeRoles(username);
- addRoles(username, roles);
- }
- }
-
- private void addRoles(String username, String[] roles) {
- for (String role : roles) {
- List<String> users = roleConfig.getList(String.class, role);
- if (users == null) {
- users = new ArrayList<>();
- }
- users.add(username);
- roleConfig.setProperty(role, StringUtil.joinStringList(users, ","));
- }
- }
-
- private void removeRoles(String username) {
-
- Iterator<String> iterKeys = roleConfig.getKeys();
-
- List<Pair<String, List<String>>> updateMap = new ArrayList<>();
- while (iterKeys.hasNext()) {
- String theRole = iterKeys.next();
-
- List<String> userList = roleConfig.getList(String.class, theRole);
- List<String> newList = new ArrayList<>();
-
- boolean roleChaned = false;
- for (String value : userList) {
- //each value may be comma separated.
- List<String> update = new ArrayList<>();
- String[] items = value.split(",");
- boolean found = false;
- for (String item : items) {
- if (!item.equals(username)) {
- update.add(item);
- } else {
- found = true;
- roleChaned = true;
- }
- }
- if (found) {
- if (update.size() > 0) {
- newList.add(StringUtil.joinStringList(update, ","));
- }
- }
- }
- if (roleChaned) {
- updateMap.add(new Pair(theRole, newList));
- }
- }
- //do update
- Iterator<Pair<String, List<String>>> iterUpdate = updateMap.iterator();
- while (iterUpdate.hasNext()) {
- Pair<String, List<String>> entry = iterUpdate.next();
- roleConfig.clearProperty(entry.getA());
- if (entry.getB().size() > 0) {
- roleConfig.addProperty(entry.getA(), entry.getB());
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/util/OptionsUtil.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/OptionsUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/OptionsUtil.java
deleted file mode 100644
index ae0aba3..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/OptionsUtil.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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 org.apache.activemq.artemis.util;
-
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.commands.Action;
-import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
-
-import java.lang.reflect.Field;
-import java.util.HashSet;
-import java.util.Set;
-
-public class OptionsUtil {
-
- public static void findAllOptions(Set<String> options, Class<? extends Action> command) {
- for (Field field : command.getDeclaredFields()) {
- if (field.isAnnotationPresent(Option.class)) {
- Option annotation = field.getAnnotation(Option.class);
- String[] names = annotation.name();
- for (String n : names) {
- options.add(n);
- }
- }
- }
- Class parent = command.getSuperclass();
- if (Action.class.isAssignableFrom(parent)) {
- findAllOptions(options, parent);
- }
- }
-
- public static Set<String> findCommandOptions(Class<? extends Action> command) {
- Set<String> options = new HashSet<>();
- findAllOptions(options, command);
-
- return options;
- }
-
- public static void checkCommandOptions(Class<? extends Action> cmdClass, String[] options) throws InvalidOptionsError {
- Set<String> definedOptions = OptionsUtil.findCommandOptions(cmdClass);
- for (String opt : options) {
- if (opt.startsWith("--") && !"--".equals(opt.trim())) {
- int index = opt.indexOf("=");
- if (index > 0) {
- opt = opt.substring(0, index);
- }
- if (!definedOptions.contains(opt)) {
- throw new InvalidOptionsError("Found unexpected parameters: [" + opt + "]");
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
index 405e777..0a22d0f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
@@ -40,10 +40,9 @@ public class ServerUtil {
}
/**
- *
* @param artemisInstance
- * @param serverName it will be used on logs
- * @param id it will be used to add on the port
+ * @param serverName it will be used on logs
+ * @param id it will be used to add on the port
* @param timeout
* @return
* @throws Exception
@@ -94,7 +93,8 @@ public class ServerUtil {
try (ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(uri, null)) {
cf.createConnection().close();
System.out.println("server " + uri + " started");
- } catch (Exception e) {
+ }
+ catch (Exception e) {
System.out.println("awaiting server " + uri + " start at ");
Thread.sleep(500);
continue;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/jaas-security
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/jaas-security b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/jaas-security
index 013a63c..b05ff70 100644
--- a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/jaas-security
+++ b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/jaas-security
@@ -14,4 +14,4 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-class=org.apache.activemq.artemis.factory.JaasSecurityHandler
+class=org.apache.activemq.artemis.cli.factory.security.JaasSecurityHandler
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/server/file
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/server/file b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/server/file
index 26ec4fb..59419dd 100644
--- a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/server/file
+++ b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/server/file
@@ -14,4 +14,4 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-class=org.apache.activemq.artemis.factory.FileBrokerHandler
+class=org.apache.activemq.artemis.cli.factory.FileBrokerHandler
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/xml b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/xml
index 28251ef..4f7943d 100644
--- a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/xml
+++ b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/xml
@@ -14,4 +14,4 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-class=org.apache.activemq.artemis.factory.XmlBrokerFactoryHandler
+class=org.apache.activemq.artemis.cli.factory.xml.XmlBrokerFactoryHandler
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/ExportFormatTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/ExportFormatTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/ExportFormatTest.java
index 16cedd2..c09218b 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/ExportFormatTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/ExportFormatTest.java
@@ -24,8 +24,8 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal;
-import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.DecodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.EncodeJournal;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Ignore;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/XmlImportExportTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/XmlImportExportTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/XmlImportExportTest.java
index 16f6462..790ed82 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/XmlImportExportTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/persistence/XmlImportExportTest.java
@@ -32,6 +32,7 @@ import java.util.Set;
import java.util.UUID;
import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
@@ -42,14 +43,13 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataExporter;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataImporter;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataExporter;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataImporter;
import org.apache.activemq.artemis.core.persistence.impl.journal.BatchingIDGenerator;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
import org.apache.activemq.artemis.core.persistence.impl.journal.LargeServerMessageImpl;
import org.apache.activemq.artemis.core.registry.JndiBindingRegistry;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.jms.server.JMSServerManager;
import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/XmlImportExportStressTest.java
----------------------------------------------------------------------
diff --git a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/XmlImportExportStressTest.java b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/XmlImportExportStressTest.java
index 9c733ac..e73687b 100644
--- a/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/XmlImportExportStressTest.java
+++ b/tests/stress-tests/src/test/java/org/apache/activemq/artemis/tests/stress/journal/XmlImportExportStressTest.java
@@ -27,8 +27,8 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataExporter;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataImporter;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataExporter;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataImporter;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
index e5650cb..b22881d 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/journal/impl/JournalImplTestBase.java
@@ -27,8 +27,8 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal;
-import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.DecodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.EncodeJournal;
import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
[2/6] activemq-artemis git commit: ARTEMIS-904 Remove cyclic
dependencies from artemis-cli
Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporter.java
new file mode 100644
index 0000000..607f92b
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporter.java
@@ -0,0 +1,627 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.xml;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.File;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import io.airlift.airline.Command;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ICoreMessage;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.cli.commands.tools.OptionalLocking;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.journal.Journal;
+import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.core.message.LargeBodyEncoder;
+import org.apache.activemq.artemis.core.paging.PagedMessage;
+import org.apache.activemq.artemis.core.paging.PagingManager;
+import org.apache.activemq.artemis.core.paging.PagingStore;
+import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
+import org.apache.activemq.artemis.core.paging.cursor.PagePosition;
+import org.apache.activemq.artemis.core.paging.cursor.impl.PagePositionImpl;
+import org.apache.activemq.artemis.core.paging.impl.Page;
+import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
+import org.apache.activemq.artemis.core.paging.impl.PagingManagerImpl;
+import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
+import org.apache.activemq.artemis.core.persistence.impl.journal.AckDescribe;
+import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
+import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.MessageDescribe;
+import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.ReferenceDescribe;
+import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
+import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
+import org.apache.activemq.artemis.core.persistence.impl.journal.codec.CursorAckRecordEncoding;
+import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageUpdateTXEncoding;
+import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentAddressBindingEncoding;
+import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentQueueBindingEncoding;
+import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.core.server.LargeServerMessage;
+import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+import org.apache.activemq.artemis.utils.ExecutorFactory;
+import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
+
+@Command(name = "exp", description = "Export all message-data using an XML that could be interpreted by any system.")
+public final class XmlDataExporter extends OptionalLocking {
+
+ private static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
+ private JournalStorageManager storageManager;
+
+ private Configuration config;
+
+ private XMLStreamWriter xmlWriter;
+
+ // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
+ private final Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs = new HashMap<>();
+
+ // map of all message records hashed by their record ID (which will match the record ID of the message refs)
+ private final HashMap<Long, Message> messages = new HashMap<>();
+
+ private final Map<Long, Set<PagePosition>> cursorRecords = new HashMap<>();
+
+ private final Set<Long> pgTXs = new HashSet<>();
+
+ private final HashMap<Long, PersistentQueueBindingEncoding> queueBindings = new HashMap<>();
+
+ private final HashMap<Long, PersistentAddressBindingEncoding> addressBindings = new HashMap<>();
+
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ super.execute(context);
+
+ try {
+ process(context.out, getBinding(), getJournal(), getPaging(), getLargeMessages());
+ } catch (Exception e) {
+ treatError(e, "data", "exp");
+ }
+ return null;
+ }
+
+ public void process(OutputStream out,
+ String bindingsDir,
+ String journalDir,
+ String pagingDir,
+ String largeMessagesDir) throws Exception {
+ config = new ConfigurationImpl().setBindingsDirectory(bindingsDir).setJournalDirectory(journalDir).setPagingDirectory(pagingDir).setLargeMessagesDirectory(largeMessagesDir).setJournalType(JournalType.NIO);
+ final ExecutorService executor = Executors.newFixedThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory());
+ ExecutorFactory executorFactory = new OrderedExecutorFactory(executor);
+
+ storageManager = new JournalStorageManager(config, executorFactory, executorFactory);
+
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out, "UTF-8");
+ PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
+ xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(), new Class[]{XMLStreamWriter.class}, handler);
+
+ writeXMLData();
+
+ executor.shutdown();
+ }
+
+ private void writeXMLData() throws Exception {
+ long start = System.currentTimeMillis();
+ getBindings();
+ processMessageJournal();
+ printDataAsXML();
+ ActiveMQServerLogger.LOGGER.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ ActiveMQServerLogger.LOGGER.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
+ }
+
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
+ private void processMessageJournal() throws Exception {
+ ArrayList<RecordInfo> acks = new ArrayList<>();
+
+ List<RecordInfo> records = new LinkedList<>();
+
+ // We load these, but don't use them.
+ List<PreparedTransactionInfo> preparedTransactions = new LinkedList<>();
+
+ Journal messageJournal = storageManager.getMessageJournal();
+
+ ActiveMQServerLogger.LOGGER.debug("Reading journal from " + config.getJournalDirectory());
+
+ messageJournal.start();
+
+ // Just logging these, no action necessary
+ TransactionFailureCallback transactionFailureCallback = new TransactionFailureCallback() {
+ @Override
+ public void failedTransaction(long transactionID,
+ List<RecordInfo> records1,
+ List<RecordInfo> recordsToDelete) {
+ StringBuilder message = new StringBuilder();
+ message.append("Encountered failed journal transaction: ").append(transactionID);
+ for (int i = 0; i < records1.size(); i++) {
+ if (i == 0) {
+ message.append("; Records: ");
+ }
+ message.append(records1.get(i));
+ if (i != (records1.size() - 1)) {
+ message.append(", ");
+ }
+ }
+
+ for (int i = 0; i < recordsToDelete.size(); i++) {
+ if (i == 0) {
+ message.append("; RecordsToDelete: ");
+ }
+ message.append(recordsToDelete.get(i));
+ if (i != (recordsToDelete.size() - 1)) {
+ message.append(", ");
+ }
+ }
+
+ ActiveMQServerLogger.LOGGER.debug(message.toString());
+ }
+ };
+
+ ((JournalImpl) messageJournal).load(records, preparedTransactions, transactionFailureCallback, false);
+
+ // Since we don't use these nullify the reference so that the garbage collector can clean them up
+ preparedTransactions = null;
+
+ for (RecordInfo info : records) {
+ byte[] data = info.data;
+
+ ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(data);
+
+ Object o = DescribeJournal.newObjectEncoding(info, storageManager);
+ if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE) {
+ messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
+ } else if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE_PROTOCOL) {
+ messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
+ } else if (info.getUserRecordType() == JournalRecordIds.ADD_LARGE_MESSAGE) {
+ messages.put(info.id, ((MessageDescribe) o).getMsg());
+ } else if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
+ ReferenceDescribe ref = (ReferenceDescribe) o;
+ HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
+ if (map == null) {
+ HashMap<Long, ReferenceDescribe> newMap = new HashMap<>();
+ newMap.put(ref.refEncoding.queueID, ref);
+ messageRefs.put(info.id, newMap);
+ } else {
+ map.put(ref.refEncoding.queueID, ref);
+ }
+ } else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
+ acks.add(info);
+ } else if (info.userRecordType == JournalRecordIds.ACKNOWLEDGE_CURSOR) {
+ CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
+ encoding.decode(buff);
+
+ Set<PagePosition> set = cursorRecords.get(encoding.queueID);
+
+ if (set == null) {
+ set = new HashSet<>();
+ cursorRecords.put(encoding.queueID, set);
+ }
+
+ set.add(encoding.position);
+ } else if (info.userRecordType == JournalRecordIds.PAGE_TRANSACTION) {
+ if (info.isUpdate) {
+ PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
+
+ pageUpdate.decode(buff);
+ pgTXs.add(pageUpdate.pageTX);
+ } else {
+ PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+
+ pageTransactionInfo.decode(buff);
+
+ pageTransactionInfo.setRecordID(info.id);
+ pgTXs.add(pageTransactionInfo.getTransactionID());
+ }
+ }
+ }
+
+ messageJournal.stop();
+
+ removeAcked(acks);
+ }
+
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
+ private void removeAcked(ArrayList<RecordInfo> acks) {
+ for (RecordInfo info : acks) {
+ AckDescribe ack = (AckDescribe) DescribeJournal.newObjectEncoding(info, null);
+ HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
+ referenceDescribeHashMap.remove(ack.refEncoding.queueID);
+ if (referenceDescribeHashMap.size() == 0) {
+ messages.remove(info.id);
+ messageRefs.remove(info.id);
+ }
+ }
+ }
+
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
+ private void getBindings() throws Exception {
+ List<RecordInfo> records = new LinkedList<>();
+
+ Journal bindingsJournal = storageManager.getBindingsJournal();
+
+ bindingsJournal.start();
+
+ ActiveMQServerLogger.LOGGER.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
+ ((JournalImpl) bindingsJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records) {
+ if (info.getUserRecordType() == JournalRecordIds.QUEUE_BINDING_RECORD) {
+ PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) DescribeJournal.newObjectEncoding(info, null);
+ queueBindings.put(bindingEncoding.getId(), bindingEncoding);
+ } else if (info.getUserRecordType() == JournalRecordIds.ADDRESS_BINDING_RECORD) {
+ PersistentAddressBindingEncoding bindingEncoding = (PersistentAddressBindingEncoding) DescribeJournal.newObjectEncoding(info, null);
+ addressBindings.put(bindingEncoding.getId(), bindingEncoding);
+ }
+ }
+
+ bindingsJournal.stop();
+ }
+
+ private void printDataAsXML() {
+ try {
+ xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
+ xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
+ printBindingsAsXML();
+ printAllMessagesAsXML();
+ xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
+ xmlWriter.writeEndDocument();
+ xmlWriter.flush();
+ xmlWriter.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void printBindingsAsXML() throws XMLStreamException {
+ xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
+ for (Map.Entry<Long, PersistentAddressBindingEncoding> addressBindingEncodingEntry : addressBindings.entrySet()) {
+ PersistentAddressBindingEncoding bindingEncoding = addressBindings.get(addressBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.ADDRESS_BINDINGS_CHILD);
+ StringBuilder routingTypes = new StringBuilder();
+ for (RoutingType routingType : bindingEncoding.getRoutingTypes()) {
+ routingTypes.append(routingType.toString()).append(", ");
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_ROUTING_TYPE, routingTypes.toString().substring(0, routingTypes.length() - 2));
+ xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_NAME, bindingEncoding.getName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
+ }
+ for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet()) {
+ PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUE_BINDINGS_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ADDRESS, bindingEncoding.getAddress().toString());
+ String filter = "";
+ if (bindingEncoding.getFilterString() != null) {
+ filter = bindingEncoding.getFilterString().toString();
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_FILTER_STRING, filter);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_NAME, bindingEncoding.getQueueName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ID, Long.toString(bindingEncoding.getId()));
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ROUTING_TYPE, RoutingType.getType(bindingEncoding.getRoutingType()).toString());
+ bindingsPrinted++;
+ }
+ xmlWriter.writeEndElement(); // end BINDINGS_PARENT
+ }
+
+ private void printAllMessagesAsXML() throws Exception {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
+ for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet()) {
+ printSingleMessageAsXML(messageMapEntry.getValue().toCore(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
+ }
+
+ printPagedMessagesAsXML();
+
+ xmlWriter.writeEndElement(); // end "messages"
+ }
+
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
+ private void printPagedMessagesAsXML() {
+ try {
+ ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1, ActiveMQThreadFactory.defaultThreadFactory());
+ final ExecutorService executor = Executors.newFixedThreadPool(10, ActiveMQThreadFactory.defaultThreadFactory());
+ ExecutorFactory executorFactory = new ExecutorFactory() {
+ @Override
+ public Executor getExecutor() {
+ return executor;
+ }
+ };
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(storageManager, config.getPagingLocation(), 1000L, scheduled, executorFactory, true, null);
+ HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<>();
+ addressSettingsRepository.setDefault(new AddressSettings());
+ PagingManager manager = new PagingManagerImpl(pageStoreFactory, addressSettingsRepository);
+
+ manager.start();
+
+ SimpleString[] stores = manager.getStoreNames();
+
+ for (SimpleString store : stores) {
+ PagingStore pageStore = manager.getPageStore(store);
+
+ if (pageStore != null) {
+ File folder = pageStore.getFolder();
+ ActiveMQServerLogger.LOGGER.debug("Reading page store " + store + " folder = " + folder);
+
+ int pageId = (int) pageStore.getFirstPage();
+ for (int i = 0; i < pageStore.getNumberOfPages(); i++) {
+ ActiveMQServerLogger.LOGGER.debug("Reading page " + pageId);
+ Page page = pageStore.createPage(pageId);
+ page.open();
+ List<PagedMessage> messages = page.read(storageManager);
+ page.close();
+
+ int messageId = 0;
+
+ for (PagedMessage message : messages) {
+ message.initMessage(storageManager);
+ long[] queueIDs = message.getQueueIDs();
+ List<String> queueNames = new ArrayList<>();
+ for (long queueID : queueIDs) {
+ PagePosition posCheck = new PagePositionImpl(pageId, messageId);
+
+ boolean acked = false;
+
+ Set<PagePosition> positions = cursorRecords.get(queueID);
+ if (positions != null) {
+ acked = positions.contains(posCheck);
+ }
+
+ if (!acked) {
+ PersistentQueueBindingEncoding queueBinding = queueBindings.get(queueID);
+ if (queueBinding != null) {
+ SimpleString queueName = queueBinding.getQueueName();
+ queueNames.add(queueName.toString());
+ }
+ }
+ }
+
+ if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID()))) {
+ printSingleMessageAsXML(message.getMessage().toCore(), queueNames);
+ }
+
+ messageId++;
+ }
+
+ pageId++;
+ }
+ } else {
+ ActiveMQServerLogger.LOGGER.debug("Page store was null");
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void printSingleMessageAsXML(ICoreMessage message, List<String> queues) throws Exception {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
+ printMessageAttributes(message);
+ printMessageProperties(message);
+ printMessageQueues(queues);
+ printMessageBody(message.toCore());
+ xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
+ }
+
+ private void printMessageBody(Message message) throws Exception {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
+ if (message.toCore().isLargeMessage()) {
+ printLargeMessageBody((LargeServerMessage) message);
+ } else {
+ xmlWriter.writeCData(XmlDataExporterUtil.encodeMessageBody(message));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
+
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ LargeBodyEncoder encoder = null;
+
+ try {
+ encoder = message.toCore().getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE) {
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE) {
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
+ } else {
+ bufferSize = remainder;
+ }
+ ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(XmlDataExporterUtil.encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
+ }
+ encoder.close();
+ } catch (ActiveMQException e) {
+ e.printStackTrace();
+ } finally {
+ if (encoder != null) {
+ try {
+ encoder.close();
+ } catch (ActiveMQException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void printMessageQueues(List<String> queues) throws XMLStreamException {
+ xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
+ for (String queueName : queues) {
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
+ }
+ xmlWriter.writeEndElement(); // end QUEUES_PARENT
+ }
+
+ private void printMessageProperties(Message message) throws XMLStreamException {
+ xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
+ for (SimpleString key : message.getPropertyNames()) {
+ Object value = message.getObjectProperty(key);
+ xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, XmlDataExporterUtil.convertProperty(value));
+
+ // Write the property type as an attribute
+ String propertyType = XmlDataExporterUtil.getPropertyType(value);
+ if (propertyType != null) {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, propertyType);
+ }
+ }
+ xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
+ }
+
+ private void printMessageAttributes(ICoreMessage message) throws XMLStreamException {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
+ String prettyType = XmlDataExporterUtil.getMessagePrettyType(message.getType());
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
+ if (message.getUserID() != null) {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
+ }
+ }
+
+ private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap) {
+ List<String> queues = new ArrayList<>();
+ for (ReferenceDescribe ref : refMap.values()) {
+ queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
+ }
+ return queues;
+ }
+
+ // Inner classes -------------------------------------------------
+
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
+ static class PrettyPrintHandler implements InvocationHandler {
+
+ private final XMLStreamWriter target;
+
+ private int depth = 0;
+
+ private static final char INDENT_CHAR = ' ';
+
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ boolean wrap = true;
+
+ PrettyPrintHandler(XMLStreamWriter target) {
+ this.target = target;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String m = method.getName();
+
+ switch (m) {
+ case "writeStartElement":
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+
+ depth++;
+ break;
+ case "writeEndElement":
+ depth--;
+ if (wrap) {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+ wrap = true;
+ break;
+ case "writeEmptyElement":
+ case "writeCData":
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ break;
+ case "writeCharacters":
+ wrap = false;
+ break;
+ }
+
+ method.invoke(target, args);
+
+ return null;
+ }
+
+ private String indent(int depth) {
+ depth *= 3; // level of indentation
+ char[] output = new char[depth];
+ while (depth-- > 0) {
+ output[depth] = INDENT_CHAR;
+ }
+ return new String(output);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporterUtil.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporterUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporterUtil.java
new file mode 100644
index 0000000..df48dcf
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataExporterUtil.java
@@ -0,0 +1,104 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.xml;
+
+import com.google.common.base.Preconditions;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.utils.Base64;
+
+/**
+ * Common utility methods to help with XML message conversion
+ */
+public class XmlDataExporterUtil {
+
+ static String convertProperty(final Object value) {
+ if (value instanceof byte[]) {
+ return encode((byte[]) value);
+ } else {
+ return value == null ? XmlDataConstants.NULL : value.toString();
+ }
+ }
+
+ static String getPropertyType(final Object value) {
+ String stringValue = null;
+
+ // if the value is null then we can't really know what it is so just set
+ // the type to the most generic thing
+ if (value == null) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES;
+ } else if (value instanceof Boolean) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_BOOLEAN;
+ } else if (value instanceof Byte) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_BYTE;
+ } else if (value instanceof Short) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_SHORT;
+ } else if (value instanceof Integer) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_INTEGER;
+ } else if (value instanceof Long) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_LONG;
+ } else if (value instanceof Float) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_FLOAT;
+ } else if (value instanceof Double) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_DOUBLE;
+ } else if (value instanceof String) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_STRING;
+ } else if (value instanceof SimpleString) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING;
+ } else if (value instanceof byte[]) {
+ stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES;
+ }
+
+ return stringValue;
+ }
+
+ public static String getMessagePrettyType(byte rawType) {
+ String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
+
+ if (rawType == Message.BYTES_TYPE) {
+ prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
+ } else if (rawType == Message.MAP_TYPE) {
+ prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
+ } else if (rawType == Message.OBJECT_TYPE) {
+ prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
+ } else if (rawType == Message.STREAM_TYPE) {
+ prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
+ } else if (rawType == Message.TEXT_TYPE) {
+ prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
+ }
+
+ return prettyType;
+ }
+
+ /**
+ * Base64 encode a ServerMessage body into the proper XML format
+ */
+ static String encodeMessageBody(final Message message) throws Exception {
+ Preconditions.checkNotNull(message, "ServerMessage can not be null");
+
+ ActiveMQBuffer byteBuffer = message.toCore().getReadOnlyBodyBuffer();
+ byte[] buffer = new byte[byteBuffer.writerIndex()];
+ byteBuffer.readBytes(buffer);
+
+ return XmlDataExporterUtil.encode(buffer);
+ }
+
+ protected static String encode(final byte[] data) {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataImporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataImporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataImporter.java
new file mode 100644
index 0000000..a824177
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataImporter.java
@@ -0,0 +1,614 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.xml;
+
+import javax.xml.XMLConstants;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
+import org.apache.activemq.artemis.api.core.ICoreMessage;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientRequestor;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.api.core.management.ManagementHelper;
+import org.apache.activemq.artemis.api.core.management.ResourceNames;
+import org.apache.activemq.artemis.cli.commands.ActionAbstract;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.apache.activemq.artemis.utils.Base64;
+import org.apache.activemq.artemis.utils.ClassloadingUtil;
+import org.apache.activemq.artemis.utils.ListUtil;
+import org.apache.activemq.artemis.utils.UUIDGenerator;
+import org.jboss.logging.Logger;
+
+/**
+ * Read XML output from <code>org.apache.activemq.artemis.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
+ * send the messages to a running instance of ActiveMQ Artemis. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ */
+@Command(name = "imp", description = "Import all message-data using an XML that could be interpreted by any system.")
+public final class XmlDataImporter extends ActionAbstract {
+
+ private static final Logger logger = Logger.getLogger(XmlDataImporter.class);
+
+ private XMLStreamReader reader;
+
+ // this session is really only needed if the "session" variable does not auto-commit sends
+ ClientSession managementSession;
+
+ boolean localSession = false;
+
+ final Map<String, String> addressMap = new HashMap<>();
+
+ final Map<String, Long> queueIDs = new HashMap<>();
+
+ String tempFileName = "";
+
+ private ClientSession session;
+
+ @Option(name = "--host", description = "The host used to import the data (default localhost)")
+ public String host = "localhost";
+
+ @Option(name = "--port", description = "The port used to import the data (default 61616)")
+ public int port = 61616;
+
+ @Option(name = "--transaction", description = "If this is set to true you will need a whole transaction to commit at the end. (default false)")
+ public boolean transactional;
+
+ @Option(name = "--user", description = "User name used to import the data. (default null)")
+ public String user = null;
+
+ @Option(name = "--password", description = "User name used to import the data. (default null)")
+ public String password = null;
+
+ @Option(name = "--input", description = "The input file name (default=exp.dmp)", required = true)
+ public String input = "exp.dmp";
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ process(input, host, port, transactional);
+ return null;
+ }
+
+ public void process(String inputFile, String host, int port, boolean transactional) throws Exception {
+ this.process(new FileInputStream(inputFile), host, port, transactional);
+ }
+
+ /**
+ * This is the normal constructor for programmatic access to the
+ * <code>org.apache.activemq.artemis.core.persistence.impl.journal.XmlDataImporter</code> if the session passed
+ * in uses auto-commit for sends.
+ * <br>
+ * If the session needs to be transactional then use the constructor which takes 2 sessions.
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, must use auto-commit for sends
+ */
+ public void process(InputStream inputStream, ClientSession session) throws Exception {
+ this.process(inputStream, session, null);
+ }
+
+ /**
+ * This is the constructor to use if you wish to import all messages transactionally.
+ * <br>
+ * Pass in a session which doesn't use auto-commit for sends, and one that does (for management
+ * operations necessary during import).
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, doesn't need to auto-commit sends
+ * @param managementSession used for management queries, must use auto-commit for sends
+ */
+ public void process(InputStream inputStream,
+ ClientSession session,
+ ClientSession managementSession) throws Exception {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ this.session = session;
+ if (managementSession != null) {
+ this.managementSession = managementSession;
+ } else {
+ this.managementSession = session;
+ }
+
+ processXml();
+
+ }
+
+ public void process(InputStream inputStream, String host, int port, boolean transactional) throws Exception {
+ HashMap<String, Object> connectionParams = new HashMap<>();
+ connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
+ connectionParams.put(TransportConstants.PORT_PROP_NAME, Integer.toString(port));
+ ServerLocator serverLocator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
+ ClientSessionFactory sf = serverLocator.createSessionFactory();
+
+ ClientSession session;
+ ClientSession managementSession;
+
+ if (user != null || password != null) {
+ session = sf.createSession(user, password, false, !transactional, true, false, 0);
+ managementSession = sf.createSession(user, password, false, true, true, false, 0);
+ } else {
+ session = sf.createSession(false, !transactional, true);
+ managementSession = sf.createSession(false, true, true);
+ }
+ localSession = true;
+
+ process(inputStream, session, managementSession);
+ }
+
+ public void validate(String file) throws Exception {
+ validate(new FileInputStream(file));
+ }
+
+ public void validate(InputStream inputStream) throws Exception {
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(XmlDataImporter.findResource("schema/artemis-import-export.xsd"));
+
+ Validator validator = schema.newValidator();
+ validator.validate(new StAXSource(reader));
+ reader.close();
+ }
+
+ private static URL findResource(final String resourceName) {
+ return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ @Override
+ public URL run() {
+ return ClassloadingUtil.findResource(resourceName);
+ }
+ });
+ }
+
+ private void processXml() throws Exception {
+ try {
+ while (reader.hasNext()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
+ }
+ if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ if (XmlDataConstants.QUEUE_BINDINGS_CHILD.equals(reader.getLocalName())) {
+ bindQueue();
+ } else if (XmlDataConstants.ADDRESS_BINDINGS_CHILD.equals(reader.getLocalName())) {
+ bindAddress();
+ } else if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName())) {
+ processMessage();
+ }
+ }
+ reader.next();
+ }
+
+ if (!session.isAutoCommitSends()) {
+ session.commit();
+ }
+ } finally {
+ // if the session was created in our constructor then close it (otherwise the caller will close it)
+ if (localSession) {
+ session.close();
+ managementSession.close();
+ }
+ }
+ }
+
+ private void processMessage() throws Exception {
+ Byte type = 0;
+ Byte priority = 0;
+ Long expiration = 0L;
+ Long timestamp = 0L;
+ org.apache.activemq.artemis.utils.UUID userId = null;
+ ArrayList<String> queues = new ArrayList<>();
+
+ // get message's attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ switch (attributeName) {
+ case XmlDataConstants.MESSAGE_TYPE:
+ type = getMessageType(reader.getAttributeValue(i));
+ break;
+ case XmlDataConstants.MESSAGE_PRIORITY:
+ priority = Byte.parseByte(reader.getAttributeValue(i));
+ break;
+ case XmlDataConstants.MESSAGE_EXPIRATION:
+ expiration = Long.parseLong(reader.getAttributeValue(i));
+ break;
+ case XmlDataConstants.MESSAGE_TIMESTAMP:
+ timestamp = Long.parseLong(reader.getAttributeValue(i));
+ break;
+ case XmlDataConstants.MESSAGE_USER_ID:
+ userId = UUIDGenerator.getInstance().generateUUID();
+ break;
+ }
+ }
+
+ Message message = session.createMessage(type, true, expiration, timestamp, priority);
+ message.setUserID(userId);
+
+ boolean endLoop = false;
+
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
+ while (reader.hasNext()) {
+ int eventType = reader.getEventType();
+ switch (eventType) {
+ case XMLStreamConstants.START_ELEMENT:
+ if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName())) {
+ processMessageBody(message.toCore());
+ } else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName())) {
+ processMessageProperties(message);
+ } else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName())) {
+ processMessageQueues(queues);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName())) {
+ endLoop = true;
+ }
+ break;
+ }
+ if (endLoop) {
+ break;
+ }
+ reader.next();
+ }
+
+ sendMessage(queues, message);
+ }
+
+ private Byte getMessageType(String value) {
+ Byte type = Message.DEFAULT_TYPE;
+ switch (value) {
+ case XmlDataConstants.DEFAULT_TYPE_PRETTY:
+ type = Message.DEFAULT_TYPE;
+ break;
+ case XmlDataConstants.BYTES_TYPE_PRETTY:
+ type = Message.BYTES_TYPE;
+ break;
+ case XmlDataConstants.MAP_TYPE_PRETTY:
+ type = Message.MAP_TYPE;
+ break;
+ case XmlDataConstants.OBJECT_TYPE_PRETTY:
+ type = Message.OBJECT_TYPE;
+ break;
+ case XmlDataConstants.STREAM_TYPE_PRETTY:
+ type = Message.STREAM_TYPE;
+ break;
+ case XmlDataConstants.TEXT_TYPE_PRETTY:
+ type = Message.TEXT_TYPE;
+ break;
+ }
+ return type;
+ }
+
+ private void sendMessage(ArrayList<String> queues, Message message) throws Exception {
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
+ ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
+ for (String queue : queues) {
+ long queueID;
+
+ if (queueIDs.containsKey(queue)) {
+ queueID = queueIDs.get(queue);
+ } else {
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
+ try (ClientRequestor requestor = new ClientRequestor(managementSession, "activemq.management")) {
+ ClientMessage managementMessage = managementSession.createMessage(false);
+ ManagementHelper.putAttribute(managementMessage, ResourceNames.QUEUE + queue, "ID");
+ managementSession.start();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Requesting ID for: " + queue);
+ }
+ ClientMessage reply = requestor.request(managementMessage);
+ Number idObject = (Number) ManagementHelper.getResult(reply);
+ queueID = idObject.longValue();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("ID for " + queue + " is: " + queueID);
+ }
+ queueIDs.put(queue, queueID); // store it so we don't have to look it up every time
+ }
+
+ logMessage.append(queue).append(", ");
+ buffer.putLong(queueID);
+ }
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ if (logger.isDebugEnabled()) {
+ logger.debug(logMessage);
+ }
+
+ message.putBytesProperty(Message.HDR_ROUTE_TO_IDS, buffer.array());
+ try (ClientProducer producer = session.createProducer(destination)) {
+ producer.send(message);
+ }
+
+ if (tempFileName.length() > 0) {
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete()) {
+ ActiveMQServerLogger.LOGGER.couldNotDeleteTempFile(tempFileName);
+ }
+ tempFileName = "";
+ }
+ }
+
+ private void processMessageQueues(ArrayList<String> queues) {
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i))) {
+ queues.add(reader.getAttributeValue(i));
+ }
+ }
+ }
+
+ private void processMessageProperties(Message message) {
+ String key = "";
+ String value = "";
+ String propertyType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ switch (attributeName) {
+ case XmlDataConstants.PROPERTY_NAME:
+ key = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.PROPERTY_VALUE:
+ value = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.PROPERTY_TYPE:
+ propertyType = reader.getAttributeValue(i);
+ break;
+ }
+ }
+
+ if (value.equals(XmlDataConstants.NULL)) {
+ value = null;
+ }
+
+ switch (propertyType) {
+ case XmlDataConstants.PROPERTY_TYPE_SHORT:
+ message.putShortProperty(key, Short.parseShort(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_BOOLEAN:
+ message.putBooleanProperty(key, Boolean.parseBoolean(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_BYTE:
+ message.putByteProperty(key, Byte.parseByte(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_BYTES:
+ message.putBytesProperty(key, value == null ? null : decode(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_DOUBLE:
+ message.putDoubleProperty(key, Double.parseDouble(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_FLOAT:
+ message.putFloatProperty(key, Float.parseFloat(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_INTEGER:
+ message.putIntProperty(key, Integer.parseInt(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_LONG:
+ message.putLongProperty(key, Long.parseLong(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING:
+ message.putStringProperty(new SimpleString(key), value == null ? null : SimpleString.toSimpleString(value));
+ break;
+ case XmlDataConstants.PROPERTY_TYPE_STRING:
+ message.putStringProperty(key, value);
+ break;
+ }
+ }
+
+ private void processMessageBody(final ICoreMessage message) throws XMLStreamException, IOException {
+ boolean isLarge = false;
+
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.MESSAGE_IS_LARGE.equals(attributeName)) {
+ isLarge = Boolean.parseBoolean(reader.getAttributeValue(i));
+ }
+ }
+ reader.next();
+ if (logger.isDebugEnabled()) {
+ logger.debug("XMLStreamReader impl: " + reader);
+ }
+ if (isLarge) {
+ tempFileName = UUID.randomUUID().toString() + ".tmp";
+ if (logger.isDebugEnabled()) {
+ logger.debug("Creating temp file " + tempFileName + " for large message.");
+ }
+ try (OutputStream out = new FileOutputStream(tempFileName)) {
+ getMessageBodyBytes(new MessageBodyBytesProcessor() {
+ @Override
+ public void processBodyBytes(byte[] bytes) throws IOException {
+ out.write(bytes);
+ }
+ });
+ }
+ FileInputStream fileInputStream = new FileInputStream(tempFileName);
+ BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
+ ((ClientMessage) message).setBodyInputStream(bufferedInput);
+ } else {
+ getMessageBodyBytes(new MessageBodyBytesProcessor() {
+ @Override
+ public void processBodyBytes(byte[] bytes) throws IOException {
+ message.getBodyBuffer().writeBytes(bytes);
+ }
+ });
+ }
+ }
+
+ /**
+ * Message bodies are written to XML as one or more Base64 encoded CDATA elements. Some parser implementations won't
+ * read an entire CDATA element at once (e.g. Woodstox) so it's possible that multiple CDATA/CHARACTERS events need
+ * to be combined to reconstruct the Base64 encoded string. You can't decode bits and pieces of each CDATA. Each
+ * CDATA has to be decoded in its entirety.
+ *
+ * @param processor used to deal with the decoded CDATA elements
+ */
+ private void getMessageBodyBytes(MessageBodyBytesProcessor processor) throws IOException, XMLStreamException {
+ int currentEventType;
+ StringBuilder cdata = new StringBuilder();
+ while (reader.hasNext()) {
+ currentEventType = reader.getEventType();
+ if (currentEventType == XMLStreamConstants.END_ELEMENT) {
+ break;
+ } else if (currentEventType == XMLStreamConstants.CHARACTERS && reader.isWhiteSpace() && cdata.length() > 0) {
+ /* when we hit a whitespace CHARACTERS event we know that the entire CDATA is complete so decode, pass back to
+ * the processor, and reset the cdata for the next event(s)
+ */
+ processor.processBodyBytes(decode(cdata.toString()));
+ cdata.setLength(0);
+ } else {
+ cdata.append(new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength()).trim());
+ }
+ reader.next();
+ }
+ }
+
+ private void bindQueue() throws Exception {
+ String queueName = "";
+ String address = "";
+ String filter = "";
+ String routingType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ switch (attributeName) {
+ case XmlDataConstants.QUEUE_BINDING_ADDRESS:
+ address = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.QUEUE_BINDING_NAME:
+ queueName = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.QUEUE_BINDING_FILTER_STRING:
+ filter = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.QUEUE_BINDING_ROUTING_TYPE:
+ routingType = reader.getAttributeValue(i);
+ break;
+ }
+ }
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
+
+ if (!queueQuery.isExists()) {
+ session.createQueue(address, RoutingType.valueOf(routingType), queueName, filter, true);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
+ }
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
+ }
+
+ addressMap.put(queueName, address);
+ }
+
+ private void bindAddress() throws Exception {
+ String addressName = "";
+ String routingTypes = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ switch (attributeName) {
+ case XmlDataConstants.ADDRESS_BINDING_NAME:
+ addressName = reader.getAttributeValue(i);
+ break;
+ case XmlDataConstants.ADDRESS_BINDING_ROUTING_TYPE:
+ routingTypes = reader.getAttributeValue(i);
+ break;
+ }
+ }
+
+ ClientSession.AddressQuery addressQuery = session.addressQuery(new SimpleString(addressName));
+
+ if (!addressQuery.isExists()) {
+ Set<RoutingType> set = new HashSet<>();
+ for (String routingType : ListUtil.toList(routingTypes)) {
+ set.add(RoutingType.valueOf(routingType));
+ }
+ session.createAddress(SimpleString.toSimpleString(addressName), set, false);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Binding address(name=" + addressName + ", routingTypes=" + routingTypes + ")");
+ }
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Binding " + addressName + " already exists so won't re-bind.");
+ }
+ }
+ }
+
+ private static byte[] decode(String data) {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ private interface MessageBodyBytesProcessor {
+ void processBodyBytes(byte[] bytes) throws IOException;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/AddUser.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/AddUser.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/AddUser.java
index caa32a7..37bd676 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/AddUser.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/AddUser.java
@@ -20,7 +20,6 @@ import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.util.HashUtil;
-import org.apache.activemq.artemis.util.FileBasedSecStoreConfig;
import org.apache.commons.lang3.StringUtils;
/**
@@ -53,7 +52,7 @@ public class AddUser extends PasswordAction {
* @param role the role
* @throws IllegalArgumentException if user exists
*/
- protected void add(String hash, String... role) throws Exception {
+ private void add(String hash, String... role) throws Exception {
FileBasedSecStoreConfig config = getConfiguration();
config.addNewUser(username, hash, role);
config.save();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/FileBasedSecStoreConfig.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/FileBasedSecStoreConfig.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/FileBasedSecStoreConfig.java
new file mode 100644
index 0000000..1f8e297
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/FileBasedSecStoreConfig.java
@@ -0,0 +1,222 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.user;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.utils.StringUtil;
+import org.apache.commons.configuration2.PropertiesConfiguration;
+import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration2.builder.fluent.Configurations;
+
+class FileBasedSecStoreConfig {
+
+ private static final String LICENSE_HEADER =
+ "## ---------------------------------------------------------------------------\n" +
+ "## Licensed to the Apache Software Foundation (ASF) under one or more\n" +
+ "## contributor license agreements. See the NOTICE file distributed with\n" +
+ "## this work for additional information regarding copyright ownership.\n" +
+ "## The ASF licenses this file to You under the Apache License, Version 2.0\n" +
+ "## (the \"License\"); you may not use this file except in compliance with\n" +
+ "## the License. You may obtain a copy of the License at\n" +
+ "##\n" +
+ "## http://www.apache.org/licenses/LICENSE-2.0\n" +
+ "##\n" +
+ "## Unless required by applicable law or agreed to in writing, software\n" +
+ "## distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
+ "## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
+ "## See the License for the specific language governing permissions and\n" +
+ "## limitations under the License.\n" +
+ "## ---------------------------------------------------------------------------\n";
+ private FileBasedConfigurationBuilder<PropertiesConfiguration> userBuilder;
+ private FileBasedConfigurationBuilder<PropertiesConfiguration> roleBuilder;
+ private PropertiesConfiguration userConfig;
+ private PropertiesConfiguration roleConfig;
+
+ FileBasedSecStoreConfig(File userFile, File roleFile) throws Exception {
+ Configurations configs = new Configurations();
+ userBuilder = configs.propertiesBuilder(userFile);
+ roleBuilder = configs.propertiesBuilder(roleFile);
+ userConfig = userBuilder.getConfiguration();
+ roleConfig = roleBuilder.getConfiguration();
+
+ String roleHeader = roleConfig.getLayout().getHeaderComment();
+ String userHeader = userConfig.getLayout().getHeaderComment();
+
+ if (userHeader == null) {
+ if (userConfig.isEmpty()) {
+ //clean and reset header
+ userConfig.clear();
+ userConfig.setHeader(LICENSE_HEADER);
+ }
+ }
+
+ if (roleHeader == null) {
+ if (roleConfig.isEmpty()) {
+ //clean and reset header
+ roleConfig.clear();
+ roleConfig.setHeader(LICENSE_HEADER);
+ }
+ }
+ }
+
+ void addNewUser(String username, String hash, String... roles) throws Exception {
+ if (userConfig.getString(username) != null) {
+ throw new IllegalArgumentException("User already exist: " + username);
+ }
+ userConfig.addProperty(username, hash);
+ addRoles(username, roles);
+ }
+
+ void save() throws Exception {
+ userBuilder.save();
+ roleBuilder.save();
+ }
+
+ void removeUser(String username) throws Exception {
+ if (userConfig.getProperty(username) == null) {
+ throw new IllegalArgumentException("user " + username + " doesn't exist.");
+ }
+ userConfig.clearProperty(username);
+ removeRoles(username);
+ }
+
+ List<String> listUser(String username) {
+ List<String> result = new ArrayList<>();
+ result.add("--- \"user\"(roles) ---\n");
+
+ int totalUsers = 0;
+ if (username != null) {
+ String roles = findRoles(username);
+ result.add("\"" + username + "\"(" + roles + ")");
+ totalUsers++;
+ } else {
+ Iterator<String> iter = userConfig.getKeys();
+ while (iter.hasNext()) {
+ String keyUser = iter.next();
+ String roles = findRoles(keyUser);
+ result.add("\"" + keyUser + "\"(" + roles + ")");
+ totalUsers++;
+ }
+ }
+ result.add("\n Total: " + totalUsers);
+ return result;
+ }
+
+ void updateUser(String username, String password, String[] roles) {
+ String oldPassword = (String) userConfig.getProperty(username);
+ if (oldPassword == null) {
+ throw new IllegalArgumentException("user " + username + " doesn't exist.");
+ }
+
+ if (password != null) {
+ userConfig.setProperty(username, password);
+ }
+
+ if (roles != null && roles.length > 0) {
+
+ removeRoles(username);
+ addRoles(username, roles);
+ }
+ }
+
+ private String findRoles(String uname) {
+ Iterator<String> iter = roleConfig.getKeys();
+ StringBuilder builder = new StringBuilder();
+ boolean first = true;
+ while (iter.hasNext()) {
+ String role = iter.next();
+ List<String> names = roleConfig.getList(String.class, role);
+ for (String value : names) {
+ //each value may be a comma separated list
+ String[] items = value.split(",");
+ for (String item : items) {
+ if (item.equals(uname)) {
+ if (!first) {
+ builder.append(",");
+ }
+ builder.append(role);
+ first = false;
+ }
+ }
+ }
+ }
+
+ return builder.toString();
+ }
+
+ private void addRoles(String username, String[] roles) {
+ for (String role : roles) {
+ List<String> users = roleConfig.getList(String.class, role);
+ if (users == null) {
+ users = new ArrayList<>();
+ }
+ users.add(username);
+ roleConfig.setProperty(role, StringUtil.joinStringList(users, ","));
+ }
+ }
+
+ private void removeRoles(String username) {
+
+ Iterator<String> iterKeys = roleConfig.getKeys();
+
+ List<Pair<String, List<String>>> updateMap = new ArrayList<>();
+ while (iterKeys.hasNext()) {
+ String theRole = iterKeys.next();
+
+ List<String> userList = roleConfig.getList(String.class, theRole);
+ List<String> newList = new ArrayList<>();
+
+ boolean roleChaned = false;
+ for (String value : userList) {
+ //each value may be comma separated.
+ List<String> update = new ArrayList<>();
+ String[] items = value.split(",");
+ boolean found = false;
+ for (String item : items) {
+ if (!item.equals(username)) {
+ update.add(item);
+ } else {
+ found = true;
+ roleChaned = true;
+ }
+ }
+ if (found) {
+ if (update.size() > 0) {
+ newList.add(StringUtil.joinStringList(update, ","));
+ }
+ }
+ }
+ if (roleChaned) {
+ updateMap.add(new Pair(theRole, newList));
+ }
+ }
+ //do update
+ Iterator<Pair<String, List<String>>> iterUpdate = updateMap.iterator();
+ while (iterUpdate.hasNext()) {
+ Pair<String, List<String>> entry = iterUpdate.next();
+ roleConfig.clearProperty(entry.getA());
+ if (entry.getB().size() > 0) {
+ roleConfig.addProperty(entry.getA(), entry.getB());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/HelpUser.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/HelpUser.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/HelpUser.java
index 36c0348..2e0ce2b 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/HelpUser.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/HelpUser.java
@@ -16,15 +16,15 @@
*/
package org.apache.activemq.artemis.cli.commands.user;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
import io.airlift.airline.Help;
import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
-import org.apache.activemq.artemis.util.OptionsUtil;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.activemq.artemis.cli.commands.OptionsUtil;
public class HelpUser extends Help implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ListUser.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ListUser.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ListUser.java
index 136a417..c0fb979 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ListUser.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ListUser.java
@@ -20,7 +20,6 @@ import java.util.List;
import io.airlift.airline.Command;
import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.util.FileBasedSecStoreConfig;
/**
* list existing users, example:
@@ -42,7 +41,7 @@ public class ListUser extends UserAction {
* list a single user or all users
* if username is not specified
*/
- protected void list() throws Exception {
+ private void list() throws Exception {
FileBasedSecStoreConfig config = getConfiguration();
List<String> result = config.listUser(username);
for (String str : result) {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/PasswordAction.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/PasswordAction.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/PasswordAction.java
index 2260488..aeba55a 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/PasswordAction.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/PasswordAction.java
@@ -24,7 +24,7 @@ public class PasswordAction extends UserAction {
@Option(name = "--password", description = "the password (Default: input)")
String password;
- protected void checkInputPassword() {
+ void checkInputPassword() {
if (password == null) {
password = inputPassword("--password", "Please provide the password:", null);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/RemoveUser.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/RemoveUser.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/RemoveUser.java
index 70167da..a9dce8d 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/RemoveUser.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/RemoveUser.java
@@ -18,7 +18,6 @@ package org.apache.activemq.artemis.cli.commands.user;
import io.airlift.airline.Command;
import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.util.FileBasedSecStoreConfig;
/**
* Remove a user, example:
@@ -35,7 +34,7 @@ public class RemoveUser extends UserAction {
return null;
}
- protected void remove() throws Exception {
+ private void remove() throws Exception {
FileBasedSecStoreConfig config = getConfiguration();
config.removeUser(username);
config.save();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ResetUser.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ResetUser.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ResetUser.java
index c219ef5..2e3e725 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ResetUser.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/ResetUser.java
@@ -20,7 +20,6 @@ import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.util.HashUtil;
-import org.apache.activemq.artemis.util.FileBasedSecStoreConfig;
import org.apache.commons.lang3.StringUtils;
/**
@@ -53,7 +52,7 @@ public class ResetUser extends PasswordAction {
return null;
}
- protected void reset(String password, String[] roles) throws Exception {
+ private void reset(String password, String[] roles) throws Exception {
if (password == null && roles == null) {
context.err.println("Nothing to update.");
return;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/UserAction.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/UserAction.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/UserAction.java
index 2f7c77f..2a23fa6 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/UserAction.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/user/UserAction.java
@@ -16,15 +16,14 @@
*/
package org.apache.activemq.artemis.cli.commands.user;
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.commands.InputAbstract;
-import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule;
-import org.apache.activemq.artemis.util.FileBasedSecStoreConfig;
-
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.io.File;
+import io.airlift.airline.Option;
+import org.apache.activemq.artemis.cli.commands.InputAbstract;
+import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule;
+
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.ROLE_FILE_PROP_NAME;
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.USER_FILE_PROP_NAME;
@@ -39,23 +38,19 @@ public abstract class UserAction extends InputAbstract {
@Option(name = "--entry", description = "The appConfigurationEntry (default: activemq)")
String entry = "activemq";
- protected void checkInputUser() {
+ void checkInputUser() {
if (username == null) {
username = input("--user", "Please provider the userName:", null);
}
}
- public void setRole(String role) {
- this.role = role;
- }
-
- public void checkInputRole() {
+ void checkInputRole() {
if (role == null) {
role = input("--role", "type a comma separated list of roles", null);
}
}
- protected FileBasedSecStoreConfig getConfiguration() throws Exception {
+ FileBasedSecStoreConfig getConfiguration() throws Exception {
Configuration securityConfig = Configuration.getConfiguration();
AppConfigurationEntry[] entries = securityConfig.getAppConfigurationEntry(entry);
@@ -82,4 +77,8 @@ public abstract class UserAction extends InputAbstract {
public void setUsername(String username) {
this.username = username;
}
+
+ public void setRole(String role) {
+ this.role = role;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ConsumerThread.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ConsumerThread.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ConsumerThread.java
deleted file mode 100644
index fc63518..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/util/ConsumerThread.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.util;
-
-import javax.jms.BytesMessage;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.Queue;
-import javax.jms.QueueBrowser;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import java.util.Enumeration;
-import java.util.concurrent.CountDownLatch;
-
-public class ConsumerThread extends Thread {
-
- int messageCount = 1000;
- int receiveTimeOut = 3000;
- Destination destination;
- Session session;
- boolean durable;
- boolean breakOnNull = true;
- int sleep;
- int batchSize;
- boolean verbose;
- boolean browse;
-
- String filter;
-
- int received = 0;
- int transactions = 0;
- boolean running = false;
- CountDownLatch finished;
- boolean bytesAsText;
-
- public ConsumerThread(Session session, Destination destination, int threadNr) {
- super("Consumer " + destination.toString() + ", thread=" + threadNr);
- this.destination = destination;
- this.session = session;
- }
-
- @Override
- public void run() {
- if (browse) {
- browse();
- } else {
- consume();
- }
- }
-
- public void browse() {
- running = true;
- QueueBrowser consumer = null;
- String threadName = Thread.currentThread().getName();
- System.out.println(threadName + " wait until " + messageCount + " messages are consumed");
- try {
- if (filter != null) {
- consumer = session.createBrowser((Queue) destination, filter);
- } else {
- consumer = session.createBrowser((Queue) destination);
- }
- Enumeration<Message> enumBrowse = consumer.getEnumeration();
-
- while (enumBrowse.hasMoreElements()) {
- Message msg = enumBrowse.nextElement();
- if (msg != null) {
- System.out.println(threadName + " Received " + (msg instanceof TextMessage ? ((TextMessage) msg).getText() : msg.getJMSMessageID()));
-
- if (verbose) {
- System.out.println("..." + msg);
- }
- if (bytesAsText && (msg instanceof BytesMessage)) {
- long length = ((BytesMessage) msg).getBodyLength();
- byte[] bytes = new byte[(int) length];
- ((BytesMessage) msg).readBytes(bytes);
- System.out.println("Message:" + msg);
- }
- received++;
-
- if (received >= messageCount) {
- break;
- }
- } else {
- break;
- }
-
- if (sleep > 0) {
- Thread.sleep(sleep);
- }
-
- }
-
- consumer.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (finished != null) {
- finished.countDown();
- }
- if (consumer != null) {
- System.out.println(threadName + " Consumed: " + this.getReceived() + " messages");
- try {
- consumer.close();
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }
- }
-
- System.out.println(threadName + " Consumer thread finished");
- }
-
- public void consume() {
- running = true;
- MessageConsumer consumer = null;
- String threadName = Thread.currentThread().getName();
- System.out.println(threadName + " wait until " + messageCount + " messages are consumed");
- try {
- if (durable && destination instanceof Topic) {
- if (filter != null) {
- consumer = session.createDurableSubscriber((Topic) destination, getName(), filter, false);
- } else {
- consumer = session.createDurableSubscriber((Topic) destination, getName());
- }
- } else {
- if (filter != null) {
- consumer = session.createConsumer(destination, filter);
- } else {
- consumer = session.createConsumer(destination);
- }
- }
- while (running && received < messageCount) {
- Message msg = consumer.receive(receiveTimeOut);
- if (msg != null) {
- System.out.println(threadName + " Received " + (msg instanceof TextMessage ? ((TextMessage) msg).getText() : msg.getJMSMessageID()));
- if (verbose) {
- System.out.println("..." + msg);
- }
- if (bytesAsText && (msg instanceof BytesMessage)) {
- long length = ((BytesMessage) msg).getBodyLength();
- byte[] bytes = new byte[(int) length];
- ((BytesMessage) msg).readBytes(bytes);
- System.out.println("Message:" + msg);
- }
- received++;
- } else {
- if (breakOnNull) {
- break;
- }
- }
-
- if (session.getTransacted()) {
- if (batchSize > 0 && received > 0 && received % batchSize == 0) {
- System.out.println(threadName + " Committing transaction: " + transactions++);
- session.commit();
- }
- } else if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) {
- if (batchSize > 0 && received > 0 && received % batchSize == 0) {
- System.out.println("Acknowledging last " + batchSize + " messages; messages so far = " + received);
- msg.acknowledge();
- }
- }
- if (sleep > 0) {
- Thread.sleep(sleep);
- }
-
- }
-
- try {
- session.commit();
- } catch (Throwable ignored) {
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (finished != null) {
- finished.countDown();
- }
- if (consumer != null) {
- System.out.println(threadName + " Consumed: " + this.getReceived() + " messages");
- try {
- consumer.close();
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }
- }
-
- System.out.println(threadName + " Consumer thread finished");
- }
-
- public int getReceived() {
- return received;
- }
-
- public boolean isDurable() {
- return durable;
- }
-
- public ConsumerThread setDurable(boolean durable) {
- this.durable = durable;
- return this;
- }
-
- public ConsumerThread setMessageCount(int messageCount) {
- this.messageCount = messageCount;
- return this;
- }
-
- public ConsumerThread setBreakOnNull(boolean breakOnNull) {
- this.breakOnNull = breakOnNull;
- return this;
- }
-
- public int getBatchSize() {
- return batchSize;
- }
-
- public ConsumerThread setBatchSize(int batchSize) {
- this.batchSize = batchSize;
- return this;
- }
-
- public int getMessageCount() {
- return messageCount;
- }
-
- public boolean isBreakOnNull() {
- return breakOnNull;
- }
-
- public int getReceiveTimeOut() {
- return receiveTimeOut;
- }
-
- public ConsumerThread setReceiveTimeOut(int receiveTimeOut) {
- this.receiveTimeOut = receiveTimeOut;
- return this;
- }
-
- public boolean isRunning() {
- return running;
- }
-
- public ConsumerThread setRunning(boolean running) {
- this.running = running;
- return this;
- }
-
- public int getSleep() {
- return sleep;
- }
-
- public ConsumerThread setSleep(int sleep) {
- this.sleep = sleep;
- return this;
- }
-
- public CountDownLatch getFinished() {
- return finished;
- }
-
- public ConsumerThread setFinished(CountDownLatch finished) {
- this.finished = finished;
- return this;
- }
-
- public boolean isBytesAsText() {
- return bytesAsText;
- }
-
- public boolean isVerbose() {
- return verbose;
- }
-
- public ConsumerThread setVerbose(boolean verbose) {
- this.verbose = verbose;
- return this;
- }
-
- public ConsumerThread setBytesAsText(boolean bytesAsText) {
- this.bytesAsText = bytesAsText;
- return this;
- }
-
- public String getFilter() {
- return filter;
- }
-
- public ConsumerThread setFilter(String filter) {
- this.filter = filter;
- return this;
- }
-
- public boolean isBrowse() {
- return browse;
- }
-
- public ConsumerThread setBrowse(boolean browse) {
- this.browse = browse;
- return this;
- }
-}
[6/6] activemq-artemis git commit: This closes #1231
Posted by jb...@apache.org.
This closes #1231
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/b9e7e7ed
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/b9e7e7ed
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/b9e7e7ed
Branch: refs/heads/master
Commit: b9e7e7ed9d358448a71af6d35b269356864f6d22
Parents: eeca06d f82623a
Author: Justin Bertram <jb...@apache.org>
Authored: Thu May 4 10:36:22 2017 -0500
Committer: Justin Bertram <jb...@apache.org>
Committed: Thu May 4 10:36:22 2017 -0500
----------------------------------------------------------------------
.../apache/activemq/artemis/cli/Artemis.java | 36 +-
.../artemis/cli/commands/ActionAbstract.java | 1 -
.../artemis/cli/commands/Configurable.java | 2 +-
.../activemq/artemis/cli/commands/Create.java | 274 ++------
.../artemis/cli/commands/HelpAction.java | 1 -
.../artemis/cli/commands/InputAbstract.java | 7 +-
.../activemq/artemis/cli/commands/Mask.java | 9 +-
.../artemis/cli/commands/OptionsUtil.java | 65 ++
.../activemq/artemis/cli/commands/Run.java | 10 +-
.../cli/commands/address/HelpAddress.java | 2 +-
.../artemis/cli/commands/messages/Browse.java | 1 -
.../artemis/cli/commands/messages/Consumer.java | 1 -
.../cli/commands/messages/ConsumerThread.java | 320 +++++++++
.../artemis/cli/commands/messages/Producer.java | 1 -
.../cli/commands/messages/ProducerThread.java | 344 +++++++++
.../artemis/cli/commands/queue/HelpQueue.java | 2 +-
.../cli/commands/tools/CompactJournal.java | 65 --
.../cli/commands/tools/DecodeJournal.java | 318 ---------
.../cli/commands/tools/EncodeJournal.java | 208 ------
.../artemis/cli/commands/tools/HelpData.java | 2 +-
.../cli/commands/tools/LockAbstract.java | 19 +-
.../artemis/cli/commands/tools/PerfJournal.java | 92 ---
.../artemis/cli/commands/tools/PrintData.java | 37 +-
.../cli/commands/tools/XmlDataConstants.java | 129 ----
.../cli/commands/tools/XmlDataExporter.java | 626 -----------------
.../cli/commands/tools/XmlDataExporterUtil.java | 107 ---
.../cli/commands/tools/XmlDataImporter.java | 690 -------------------
.../commands/tools/journal/CompactJournal.java | 66 ++
.../commands/tools/journal/DecodeJournal.java | 296 ++++++++
.../commands/tools/journal/EncodeJournal.java | 191 +++++
.../cli/commands/tools/journal/PerfJournal.java | 92 +++
.../commands/tools/xml/XmlDataConstants.java | 81 +++
.../cli/commands/tools/xml/XmlDataExporter.java | 627 +++++++++++++++++
.../commands/tools/xml/XmlDataExporterUtil.java | 104 +++
.../cli/commands/tools/xml/XmlDataImporter.java | 614 +++++++++++++++++
.../artemis/cli/commands/user/AddUser.java | 3 +-
.../commands/user/FileBasedSecStoreConfig.java | 222 ++++++
.../artemis/cli/commands/user/HelpUser.java | 10 +-
.../artemis/cli/commands/user/ListUser.java | 3 +-
.../cli/commands/user/PasswordAction.java | 2 +-
.../artemis/cli/commands/user/RemoveUser.java | 3 +-
.../artemis/cli/commands/user/ResetUser.java | 3 +-
.../artemis/cli/commands/user/UserAction.java | 23 +-
.../cli/commands/util/ConsumerThread.java | 320 ---------
.../cli/commands/util/ProducerThread.java | 344 ---------
.../artemis/cli/factory/BrokerFactory.java | 73 ++
.../cli/factory/BrokerFactoryHandler.java | 26 +
.../artemis/cli/factory/BrokerHandler.java | 26 +
.../artemis/cli/factory/FileBrokerHandler.java | 30 +
.../factory/security/JaasSecurityHandler.java | 31 +
.../cli/factory/security/SecurityHandler.java | 25 +
.../security/SecurityManagerFactory.java | 35 +
.../factory/xml/XmlBrokerFactoryHandler.java | 37 +
.../activemq/artemis/factory/BrokerFactory.java | 82 ---
.../artemis/factory/BrokerFactoryHandler.java | 28 -
.../activemq/artemis/factory/BrokerHandler.java | 26 -
.../artemis/factory/FileBrokerHandler.java | 30 -
.../artemis/factory/JaasSecurityHandler.java | 32 -
.../artemis/factory/SecurityHandler.java | 25 -
.../artemis/factory/SecurityManagerFactory.java | 37 -
.../factory/XmlBrokerFactoryHandler.java | 41 --
.../artemis/integration/FileBroker.java | 4 +-
.../artemis/util/FileBasedSecStoreConfig.java | 222 ------
.../activemq/artemis/util/OptionsUtil.java | 67 --
.../activemq/artemis/util/ServerUtil.java | 8 +-
.../artemis/broker/security/jaas-security | 2 +-
.../apache/activemq/artemis/broker/server/file | 2 +-
.../org/apache/activemq/artemis/broker/xml | 2 +-
.../persistence/ExportFormatTest.java | 4 +-
.../persistence/XmlImportExportTest.java | 6 +-
.../journal/XmlImportExportStressTest.java | 4 +-
.../core/journal/impl/JournalImplTestBase.java | 4 +-
72 files changed, 3466 insertions(+), 3816 deletions(-)
----------------------------------------------------------------------
[3/6] activemq-artemis git commit: ARTEMIS-904 Remove cyclic
dependencies from artemis-cli
Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataImporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataImporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataImporter.java
deleted file mode 100644
index 518d231..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataImporter.java
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import javax.xml.XMLConstants;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.transform.stax.StAXSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import io.airlift.airline.Command;
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.api.core.ICoreMessage;
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.RoutingType;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.api.core.client.ClientMessage;
-import org.apache.activemq.artemis.api.core.client.ClientProducer;
-import org.apache.activemq.artemis.api.core.client.ClientRequestor;
-import org.apache.activemq.artemis.api.core.client.ClientSession;
-import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.api.core.management.ManagementHelper;
-import org.apache.activemq.artemis.api.core.management.ResourceNames;
-import org.apache.activemq.artemis.cli.commands.ActionAbstract;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
-import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
-import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
-import org.apache.activemq.artemis.utils.Base64;
-import org.apache.activemq.artemis.utils.ClassloadingUtil;
-import org.apache.activemq.artemis.utils.ListUtil;
-import org.apache.activemq.artemis.utils.UUIDGenerator;
-import org.jboss.logging.Logger;
-
-/**
- * Read XML output from <code>org.apache.activemq.artemis.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
- * send the messages to a running instance of ActiveMQ Artemis. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
- * for speed and simplicity.
- */
-@Command(name = "imp", description = "Import all message-data using an XML that could be interpreted by any system.")
-public final class XmlDataImporter extends ActionAbstract {
- // Constants -----------------------------------------------------
-
- private static final Logger logger = Logger.getLogger(XmlDataImporter.class);
-
- // Attributes ----------------------------------------------------
-
- private XMLStreamReader reader;
-
- // this session is really only needed if the "session" variable does not auto-commit sends
- ClientSession managementSession;
-
- boolean localSession = false;
-
- final Map<String, String> addressMap = new HashMap<>();
-
- final Map<String, Long> queueIDs = new HashMap<>();
-
- String tempFileName = "";
-
- private ClientSession session;
-
- @Option(name = "--host", description = "The host used to import the data (default localhost)")
- public String host = "localhost";
-
- @Option(name = "--port", description = "The port used to import the data (default 61616)")
- public int port = 61616;
-
- @Option(name = "--transaction", description = "If this is set to true you will need a whole transaction to commit at the end. (default false)")
- public boolean transactional;
-
- @Option(name = "--user", description = "User name used to import the data. (default null)")
- public String user = null;
-
- @Option(name = "--password", description = "User name used to import the data. (default null)")
- public String password = null;
-
- @Option(name = "--input", description = "The input file name (default=exp.dmp)", required = true)
- public String input = "exp.dmp";
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getUser() {
- return user;
- }
-
- public void setUser(String user) {
- this.user = user;
- }
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- process(input, host, port, transactional);
- return null;
- }
-
- public void process(String inputFile, String host, int port, boolean transactional) throws Exception {
- this.process(new FileInputStream(inputFile), host, port, transactional);
- }
-
- /**
- * This is the normal constructor for programmatic access to the
- * <code>org.apache.activemq.artemis.core.persistence.impl.journal.XmlDataImporter</code> if the session passed
- * in uses auto-commit for sends.
- * <br>
- * If the session needs to be transactional then use the constructor which takes 2 sessions.
- *
- * @param inputStream the stream from which to read the XML for import
- * @param session used for sending messages, must use auto-commit for sends
- * @throws Exception
- */
- public void process(InputStream inputStream, ClientSession session) throws Exception {
- this.process(inputStream, session, null);
- }
-
- /**
- * This is the constructor to use if you wish to import all messages transactionally.
- * <br>
- * Pass in a session which doesn't use auto-commit for sends, and one that does (for management
- * operations necessary during import).
- *
- * @param inputStream the stream from which to read the XML for import
- * @param session used for sending messages, doesn't need to auto-commit sends
- * @param managementSession used for management queries, must use auto-commit for sends
- */
- public void process(InputStream inputStream,
- ClientSession session,
- ClientSession managementSession) throws Exception {
- reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
- this.session = session;
- if (managementSession != null) {
- this.managementSession = managementSession;
- } else {
- this.managementSession = session;
- }
-
- processXml();
-
- }
-
- public void process(InputStream inputStream, String host, int port, boolean transactional) throws Exception {
- HashMap<String, Object> connectionParams = new HashMap<>();
- connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
- connectionParams.put(TransportConstants.PORT_PROP_NAME, Integer.toString(port));
- ServerLocator serverLocator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
- ClientSessionFactory sf = serverLocator.createSessionFactory();
-
- ClientSession session;
- ClientSession managementSession;
-
- if (user != null || password != null) {
- session = sf.createSession(user, password, false, !transactional, true, false, 0);
- managementSession = sf.createSession(user, password, false, true, true, false, 0);
- } else {
- session = sf.createSession(false, !transactional, true);
- managementSession = sf.createSession(false, true, true);
- }
- localSession = true;
-
- process(inputStream, session, managementSession);
- }
-
- public void validate(String file) throws Exception {
- validate(new FileInputStream(file));
- }
-
- public void validate(InputStream inputStream) throws Exception {
- XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
- SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- Schema schema = factory.newSchema(XmlDataImporter.findResource("schema/artemis-import-export.xsd"));
-
- Validator validator = schema.newValidator();
- validator.validate(new StAXSource(reader));
- reader.close();
- }
-
- private static URL findResource(final String resourceName) {
- return AccessController.doPrivileged(new PrivilegedAction<URL>() {
- @Override
- public URL run() {
- return ClassloadingUtil.findResource(resourceName);
- }
- });
- }
-
- private void processXml() throws Exception {
- try {
- while (reader.hasNext()) {
- if (logger.isDebugEnabled()) {
- logger.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
- }
- if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) {
- if (XmlDataConstants.QUEUE_BINDINGS_CHILD.equals(reader.getLocalName())) {
- bindQueue();
- } else if (XmlDataConstants.ADDRESS_BINDINGS_CHILD.equals(reader.getLocalName())) {
- bindAddress();
- } else if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName())) {
- processMessage();
- }
- }
- reader.next();
- }
-
- if (!session.isAutoCommitSends()) {
- session.commit();
- }
- } finally {
- // if the session was created in our constructor then close it (otherwise the caller will close it)
- if (localSession) {
- session.close();
- managementSession.close();
- }
- }
- }
-
- private void processMessage() throws Exception {
- Byte type = 0;
- Byte priority = 0;
- Long expiration = 0L;
- Long timestamp = 0L;
- org.apache.activemq.artemis.utils.UUID userId = null;
- ArrayList<String> queues = new ArrayList<>();
-
- // get message's attributes
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- String attributeName = reader.getAttributeLocalName(i);
- switch (attributeName) {
- case XmlDataConstants.MESSAGE_TYPE:
- type = getMessageType(reader.getAttributeValue(i));
- break;
- case XmlDataConstants.MESSAGE_PRIORITY:
- priority = Byte.parseByte(reader.getAttributeValue(i));
- break;
- case XmlDataConstants.MESSAGE_EXPIRATION:
- expiration = Long.parseLong(reader.getAttributeValue(i));
- break;
- case XmlDataConstants.MESSAGE_TIMESTAMP:
- timestamp = Long.parseLong(reader.getAttributeValue(i));
- break;
- case XmlDataConstants.MESSAGE_USER_ID:
- userId = UUIDGenerator.getInstance().generateUUID();
- break;
- }
- }
-
- Message message = session.createMessage(type, true, expiration, timestamp, priority);
- message.setUserID(userId);
-
- boolean endLoop = false;
-
- // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
- while (reader.hasNext()) {
- int eventType = reader.getEventType();
- switch (eventType) {
- case XMLStreamConstants.START_ELEMENT:
- if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName())) {
- processMessageBody(message.toCore());
- } else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName())) {
- processMessageProperties(message);
- } else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName())) {
- processMessageQueues(queues);
- }
- break;
- case XMLStreamConstants.END_ELEMENT:
- if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName())) {
- endLoop = true;
- }
- break;
- }
- if (endLoop) {
- break;
- }
- reader.next();
- }
-
- sendMessage(queues, message);
- }
-
- private Byte getMessageType(String value) {
- Byte type = Message.DEFAULT_TYPE;
- switch (value) {
- case XmlDataConstants.DEFAULT_TYPE_PRETTY:
- type = Message.DEFAULT_TYPE;
- break;
- case XmlDataConstants.BYTES_TYPE_PRETTY:
- type = Message.BYTES_TYPE;
- break;
- case XmlDataConstants.MAP_TYPE_PRETTY:
- type = Message.MAP_TYPE;
- break;
- case XmlDataConstants.OBJECT_TYPE_PRETTY:
- type = Message.OBJECT_TYPE;
- break;
- case XmlDataConstants.STREAM_TYPE_PRETTY:
- type = Message.STREAM_TYPE;
- break;
- case XmlDataConstants.TEXT_TYPE_PRETTY:
- type = Message.TEXT_TYPE;
- break;
- }
- return type;
- }
-
- private void sendMessage(ArrayList<String> queues, Message message) throws Exception {
- StringBuilder logMessage = new StringBuilder();
- String destination = addressMap.get(queues.get(0));
-
- logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
- ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
-
- for (String queue : queues) {
- long queueID;
-
- if (queueIDs.containsKey(queue)) {
- queueID = queueIDs.get(queue);
- } else {
- // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
- // send directly to a queue, we have to send to an address instead but not all the queues related to the
- // address may need the message
- try (ClientRequestor requestor = new ClientRequestor(managementSession, "activemq.management")) {
- ClientMessage managementMessage = managementSession.createMessage(false);
- ManagementHelper.putAttribute(managementMessage, ResourceNames.QUEUE + queue, "ID");
- managementSession.start();
- if (logger.isDebugEnabled()) {
- logger.debug("Requesting ID for: " + queue);
- }
- ClientMessage reply = requestor.request(managementMessage);
- Number idObject = (Number) ManagementHelper.getResult(reply);
- queueID = idObject.longValue();
- }
- if (logger.isDebugEnabled()) {
- logger.debug("ID for " + queue + " is: " + queueID);
- }
- queueIDs.put(queue, queueID); // store it so we don't have to look it up every time
- }
-
- logMessage.append(queue).append(", ");
- buffer.putLong(queueID);
- }
-
- logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
- if (logger.isDebugEnabled()) {
- logger.debug(logMessage);
- }
-
- message.putBytesProperty(Message.HDR_ROUTE_TO_IDS, buffer.array());
- try (ClientProducer producer = session.createProducer(destination)) {
- producer.send(message);
- }
-
- if (tempFileName.length() > 0) {
- File tempFile = new File(tempFileName);
- if (!tempFile.delete()) {
- ActiveMQServerLogger.LOGGER.couldNotDeleteTempFile(tempFileName);
- }
- tempFileName = "";
- }
- }
-
- private void processMessageQueues(ArrayList<String> queues) {
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i))) {
- queues.add(reader.getAttributeValue(i));
- }
- }
- }
-
- private void processMessageProperties(Message message) {
- String key = "";
- String value = "";
- String propertyType = "";
- String realStringValue = null;
- SimpleString realSimpleStringValue = null;
-
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- String attributeName = reader.getAttributeLocalName(i);
- switch (attributeName) {
- case XmlDataConstants.PROPERTY_NAME:
- key = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.PROPERTY_VALUE:
- value = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.PROPERTY_TYPE:
- propertyType = reader.getAttributeValue(i);
- break;
- }
- }
-
- if (value.equals(XmlDataConstants.NULL)) {
- value = null;
- }
-
- switch (propertyType) {
- case XmlDataConstants.PROPERTY_TYPE_SHORT:
- message.putShortProperty(key, Short.parseShort(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_BOOLEAN:
- message.putBooleanProperty(key, Boolean.parseBoolean(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_BYTE:
- message.putByteProperty(key, Byte.parseByte(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_BYTES:
- message.putBytesProperty(key, value == null ? null : decode(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_DOUBLE:
- message.putDoubleProperty(key, Double.parseDouble(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_FLOAT:
- message.putFloatProperty(key, Float.parseFloat(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_INTEGER:
- message.putIntProperty(key, Integer.parseInt(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_LONG:
- message.putLongProperty(key, Long.parseLong(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING:
- message.putStringProperty(new SimpleString(key), value == null ? null : SimpleString.toSimpleString(value));
- break;
- case XmlDataConstants.PROPERTY_TYPE_STRING:
- message.putStringProperty(key, value);
- break;
- }
- }
-
- private void processMessageBody(final ICoreMessage message) throws XMLStreamException, IOException {
- boolean isLarge = false;
-
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- String attributeName = reader.getAttributeLocalName(i);
- if (XmlDataConstants.MESSAGE_IS_LARGE.equals(attributeName)) {
- isLarge = Boolean.parseBoolean(reader.getAttributeValue(i));
- }
- }
- reader.next();
- if (logger.isDebugEnabled()) {
- logger.debug("XMLStreamReader impl: " + reader);
- }
- if (isLarge) {
- tempFileName = UUID.randomUUID().toString() + ".tmp";
- if (logger.isDebugEnabled()) {
- logger.debug("Creating temp file " + tempFileName + " for large message.");
- }
- try (OutputStream out = new FileOutputStream(tempFileName)) {
- getMessageBodyBytes(new MessageBodyBytesProcessor() {
- @Override
- public void processBodyBytes(byte[] bytes) throws IOException {
- out.write(bytes);
- }
- });
- }
- FileInputStream fileInputStream = new FileInputStream(tempFileName);
- BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
- ((ClientMessage) message).setBodyInputStream(bufferedInput);
- } else {
- getMessageBodyBytes(new MessageBodyBytesProcessor() {
- @Override
- public void processBodyBytes(byte[] bytes) throws IOException {
- message.getBodyBuffer().writeBytes(bytes);
- }
- });
- }
- }
-
- /**
- * Message bodies are written to XML as one or more Base64 encoded CDATA elements. Some parser implementations won't
- * read an entire CDATA element at once (e.g. Woodstox) so it's possible that multiple CDATA/CHARACTERS events need
- * to be combined to reconstruct the Base64 encoded string. You can't decode bits and pieces of each CDATA. Each
- * CDATA has to be decoded in its entirety.
- *
- * @param processor used to deal with the decoded CDATA elements
- * @throws IOException
- * @throws XMLStreamException
- */
- private void getMessageBodyBytes(MessageBodyBytesProcessor processor) throws IOException, XMLStreamException {
- int currentEventType;
- StringBuilder cdata = new StringBuilder();
- while (reader.hasNext()) {
- currentEventType = reader.getEventType();
- if (currentEventType == XMLStreamConstants.END_ELEMENT) {
- break;
- } else if (currentEventType == XMLStreamConstants.CHARACTERS && reader.isWhiteSpace() && cdata.length() > 0) {
- /* when we hit a whitespace CHARACTERS event we know that the entire CDATA is complete so decode, pass back to
- * the processor, and reset the cdata for the next event(s)
- */
- processor.processBodyBytes(decode(cdata.toString()));
- cdata.setLength(0);
- } else {
- cdata.append(new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength()).trim());
- }
- reader.next();
- }
- }
-
- private void bindQueue() throws Exception {
- String queueName = "";
- String address = "";
- String filter = "";
- String routingType = "";
-
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- String attributeName = reader.getAttributeLocalName(i);
- switch (attributeName) {
- case XmlDataConstants.QUEUE_BINDING_ADDRESS:
- address = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.QUEUE_BINDING_NAME:
- queueName = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.QUEUE_BINDING_FILTER_STRING:
- filter = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.QUEUE_BINDING_ROUTING_TYPE:
- routingType = reader.getAttributeValue(i);
- break;
- }
- }
-
- ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
-
- if (!queueQuery.isExists()) {
- session.createQueue(address, RoutingType.valueOf(routingType), queueName, filter, true);
- if (logger.isDebugEnabled()) {
- logger.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Binding " + queueName + " already exists so won't re-bind.");
- }
- }
-
- addressMap.put(queueName, address);
- }
-
- private void bindAddress() throws Exception {
- String addressName = "";
- String routingTypes = "";
-
- for (int i = 0; i < reader.getAttributeCount(); i++) {
- String attributeName = reader.getAttributeLocalName(i);
- switch (attributeName) {
- case XmlDataConstants.ADDRESS_BINDING_NAME:
- addressName = reader.getAttributeValue(i);
- break;
- case XmlDataConstants.ADDRESS_BINDING_ROUTING_TYPE:
- routingTypes = reader.getAttributeValue(i);
- break;
- }
- }
-
- ClientSession.AddressQuery addressQuery = session.addressQuery(new SimpleString(addressName));
-
- if (!addressQuery.isExists()) {
- Set<RoutingType> set = new HashSet<>();
- for (String routingType : ListUtil.toList(routingTypes)) {
- set.add(RoutingType.valueOf(routingType));
- }
- session.createAddress(SimpleString.toSimpleString(addressName), set, false);
- if (logger.isDebugEnabled()) {
- logger.debug("Binding address(name=" + addressName + ", routingTypes=" + routingTypes + ")");
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Binding " + addressName + " already exists so won't re-bind.");
- }
- }
- }
-
- private String getEntries() throws Exception {
- StringBuilder entry = new StringBuilder();
- boolean endLoop = false;
-
- while (reader.hasNext()) {
- int eventType = reader.getEventType();
- switch (eventType) {
- case XMLStreamConstants.START_ELEMENT:
- if (XmlDataConstants.JMS_JNDI_ENTRY.equals(reader.getLocalName())) {
- String elementText = reader.getElementText();
- entry.append(elementText).append(", ");
- if (logger.isDebugEnabled()) {
- logger.debug("JMS admin object JNDI entry: " + entry.toString());
- }
- }
- break;
- case XMLStreamConstants.END_ELEMENT:
- if (XmlDataConstants.JMS_JNDI_ENTRIES.equals(reader.getLocalName())) {
- endLoop = true;
- }
- break;
- }
- if (endLoop) {
- break;
- }
- reader.next();
- }
-
- return entry.delete(entry.length() - 2, entry.length()).toString();
- }
-
- private String getConnectors() throws Exception {
- StringBuilder entry = new StringBuilder();
- boolean endLoop = false;
-
- while (reader.hasNext()) {
- int eventType = reader.getEventType();
- switch (eventType) {
- case XMLStreamConstants.START_ELEMENT:
- if (XmlDataConstants.JMS_CONNECTION_FACTORY_CONNECTOR.equals(reader.getLocalName())) {
- entry.append(reader.getElementText()).append(", ");
- }
- break;
- case XMLStreamConstants.END_ELEMENT:
- if (XmlDataConstants.JMS_CONNECTION_FACTORY_CONNECTORS.equals(reader.getLocalName())) {
- endLoop = true;
- }
- break;
- }
- if (endLoop) {
- break;
- }
- reader.next();
- }
-
- return entry.delete(entry.length() - 2, entry.length()).toString();
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- private static byte[] decode(String data) {
- return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
- private interface MessageBodyBytesProcessor {
-
- void processBodyBytes(byte[] bytes) throws IOException;
- }
-
- // Inner classes -------------------------------------------------
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/CompactJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/CompactJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/CompactJournal.java
new file mode 100644
index 0000000..347bd4b
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/CompactJournal.java
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.journal;
+
+import java.io.File;
+
+import io.airlift.airline.Command;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+
+@Command(name = "compact", description = "Compacts the journal of a non running server")
+public final class CompactJournal extends LockAbstract {
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ super.execute(context);
+ try {
+ Configuration configuration = getFileConfiguration();
+ compactJournal(new File(getJournal()), "activemq-data", "amq", configuration.getJournalMinFiles(), configuration.getJournalFileSize(), null);
+ System.out.println("Compactation succeeded for " + getJournal());
+ compactJournal(new File(getBinding()), "activemq-bindings", "bindings", 2, 1048576, null);
+ System.out.println("Compactation succeeded for " + getBinding());
+
+ } catch (Exception e) {
+ treatError(e, "data", "compact");
+ }
+ return null;
+ }
+
+ private void compactJournal(final File directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final IOCriticalErrorListener listener) throws Exception {
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener, 1);
+
+ JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
+
+ journal.start();
+
+ journal.loadInternalOnly();
+
+ journal.compact();
+
+ journal.stop();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/DecodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/DecodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/DecodeJournal.java
new file mode 100644
index 0000000..35a4ae2
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/DecodeJournal.java
@@ -0,0 +1,296 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.journal;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.utils.Base64;
+
+@Command(name = "decode", description = "Decode a journal's internal format into a new journal set of files")
+public class DecodeJournal extends LockAbstract {
+
+ @Option(name = "--directory", description = "The journal folder (default journal folder from broker.xml)")
+ public String directory;
+
+ @Option(name = "--prefix", description = "The journal prefix (default activemq-data)")
+ public String prefix = "activemq-data";
+
+ @Option(name = "--suffix", description = "The journal suffix (default amq)")
+ public String suffix = "amq";
+
+ @Option(name = "--file-size", description = "The journal size (default 10485760)")
+ public int size = 10485760;
+
+ @Option(name = "--input", description = "The input file name (default=exp.dmp)", required = true)
+ public String input = "exp.dmp";
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ super.execute(context);
+ try {
+ if (directory == null) {
+ directory = getFileConfiguration().getJournalDirectory();
+ }
+ importJournal(directory, prefix, suffix, 2, size, input);
+ } catch (Exception e) {
+ treatError(e, "data", "decode");
+ }
+
+ return null;
+ }
+
+ public static void importJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final String fileInput) throws Exception {
+ FileInputStream fileInputStream = new FileInputStream(new File(fileInput));
+ importJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, fileInputStream);
+
+ }
+
+ private static void importJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final InputStream stream) throws Exception {
+ Reader reader = new InputStreamReader(stream);
+ importJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, reader);
+ }
+
+ public static void importJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final Reader reader) throws Exception {
+
+ File journalDir = new File(directory);
+
+ if (!journalDir.exists()) {
+ if (!journalDir.mkdirs())
+ System.err.println("Could not create directory " + directory);
+ }
+
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
+
+ JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
+
+ if (journal.orderFiles().size() != 0) {
+ throw new IllegalStateException("Import needs to create a brand new journal");
+ }
+
+ journal.start();
+
+ // The journal is empty, as we checked already. Calling load just to initialize the internal data
+ journal.loadInternalOnly();
+
+ BufferedReader buffReader = new BufferedReader(reader);
+
+ String line;
+
+ HashMap<Long, AtomicInteger> txCounters = new HashMap<>();
+
+ long lineNumber = 0;
+
+ while ((line = buffReader.readLine()) != null) {
+ lineNumber++;
+ String[] splitLine = line.split(",");
+ if (splitLine[0].equals("#File")) {
+ txCounters.clear();
+ continue;
+ }
+
+ Properties lineProperties = parseLine(splitLine);
+
+ String operation = null;
+ try {
+ operation = lineProperties.getProperty("operation");
+
+ if (operation.equals("AddRecord")) {
+ RecordInfo info = parseRecord(lineProperties);
+ journal.appendAddRecord(info.id, info.userRecordType, info.data, false);
+ } else if (operation.equals("AddRecordTX")) {
+ long txID = parseLong("txID", lineProperties);
+ AtomicInteger counter = getCounter(txID, txCounters);
+ counter.incrementAndGet();
+ RecordInfo info = parseRecord(lineProperties);
+ journal.appendAddRecordTransactional(txID, info.id, info.userRecordType, info.data);
+ } else if (operation.equals("UpdateTX")) {
+ long txID = parseLong("txID", lineProperties);
+ AtomicInteger counter = getCounter(txID, txCounters);
+ counter.incrementAndGet();
+ RecordInfo info = parseRecord(lineProperties);
+ journal.appendUpdateRecordTransactional(txID, info.id, info.userRecordType, info.data);
+ } else if (operation.equals("Update")) {
+ RecordInfo info = parseRecord(lineProperties);
+ journal.appendUpdateRecord(info.id, info.userRecordType, info.data, false);
+ } else if (operation.equals("DeleteRecord")) {
+ long id = parseLong("id", lineProperties);
+
+ try {
+ journal.appendDeleteRecord(id, false);
+ } catch (IllegalStateException ignored) {
+ // If not found it means the append/update records were reclaimed already
+ }
+ } else if (operation.equals("DeleteRecordTX")) {
+ long txID = parseLong("txID", lineProperties);
+ long id = parseLong("id", lineProperties);
+ AtomicInteger counter = getCounter(txID, txCounters);
+ counter.incrementAndGet();
+ journal.appendDeleteRecordTransactional(txID, id);
+ } else if (operation.equals("Prepare")) {
+ long txID = parseLong("txID", lineProperties);
+ int numberOfRecords = parseInt("numberOfRecords", lineProperties);
+ AtomicInteger counter = getCounter(txID, txCounters);
+ byte[] data = parseEncoding("extraData", lineProperties);
+
+ if (counter.get() == numberOfRecords) {
+ journal.appendPrepareRecord(txID, data, false);
+ } else {
+ System.err.println("Transaction " + txID +
+ " at line " +
+ lineNumber +
+ " is incomplete. The prepare record expected " +
+ numberOfRecords +
+ " while the import only had " +
+ counter);
+ }
+ } else if (operation.equals("Commit")) {
+ long txID = parseLong("txID", lineProperties);
+ int numberOfRecords = parseInt("numberOfRecords", lineProperties);
+ AtomicInteger counter = getCounter(txID, txCounters);
+ if (counter.get() == numberOfRecords) {
+ journal.appendCommitRecord(txID, false);
+ } else {
+ System.err.println("Transaction " + txID +
+ " at line " +
+ lineNumber +
+ " is incomplete. The commit record expected " +
+ numberOfRecords +
+ " while the import only had " +
+ counter);
+ }
+ } else if (operation.equals("Rollback")) {
+ long txID = parseLong("txID", lineProperties);
+ journal.appendRollbackRecord(txID, false);
+ } else {
+ System.err.println("Invalid operation " + operation + " at line " + lineNumber);
+ }
+ } catch (Exception ex) {
+ System.err.println("Error at line " + lineNumber + ", operation=" + operation + " msg = " + ex.getMessage());
+ }
+ }
+
+ journal.stop();
+ }
+
+ private static AtomicInteger getCounter(final Long txID, final Map<Long, AtomicInteger> txCounters) {
+ AtomicInteger counter = txCounters.get(txID);
+ if (counter == null) {
+ counter = new AtomicInteger(0);
+ txCounters.put(txID, counter);
+ }
+
+ return counter;
+ }
+
+ private static RecordInfo parseRecord(final Properties properties) throws Exception {
+ long id = parseLong("id", properties);
+ byte userRecordType = parseByte("userRecordType", properties);
+ boolean isUpdate = parseBoolean("isUpdate", properties);
+ byte[] data = parseEncoding("data", properties);
+ return new RecordInfo(id, userRecordType, data, isUpdate, (short) 0);
+ }
+
+ private static byte[] parseEncoding(final String name, final Properties properties) throws Exception {
+ String value = parseString(name, properties);
+
+ return decode(value);
+ }
+
+ private static int parseInt(final String name, final Properties properties) throws Exception {
+ String value = parseString(name, properties);
+
+ return Integer.parseInt(value);
+ }
+
+ private static long parseLong(final String name, final Properties properties) throws Exception {
+ String value = parseString(name, properties);
+
+ return Long.parseLong(value);
+ }
+
+ private static boolean parseBoolean(final String name, final Properties properties) throws Exception {
+ String value = parseString(name, properties);
+
+ return Boolean.parseBoolean(value);
+ }
+
+ private static byte parseByte(final String name, final Properties properties) throws Exception {
+ String value = parseString(name, properties);
+
+ return Byte.parseByte(value);
+ }
+
+ private static String parseString(final String name, final Properties properties) throws Exception {
+ String value = properties.getProperty(name);
+
+ if (value == null) {
+ throw new Exception("property " + name + " not found");
+ }
+ return value;
+ }
+
+ private static Properties parseLine(final String[] splitLine) {
+ Properties properties = new Properties();
+
+ for (String el : splitLine) {
+ String[] tuple = el.split("@");
+ if (tuple.length == 2) {
+ properties.put(tuple[0], tuple[1]);
+ } else {
+ properties.put(tuple[0], tuple[0]);
+ }
+ }
+
+ return properties;
+ }
+
+ private static byte[] decode(final String data) {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/EncodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/EncodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/EncodeJournal.java
new file mode 100644
index 0000000..ec47837
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/EncodeJournal.java
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.journal;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
+import org.apache.activemq.artemis.core.io.SequentialFileFactory;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.journal.impl.JournalFile;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
+import org.apache.activemq.artemis.utils.Base64;
+
+@Command(name = "encode", description = "Encode a set of journal files into an internal encoded data format")
+public class EncodeJournal extends LockAbstract {
+
+ @Option(name = "--directory", description = "The journal folder (default the journal folder from broker.xml)")
+ public String directory;
+
+ @Option(name = "--prefix", description = "The journal prefix (default activemq-data)")
+ public String prefix = "activemq-data";
+
+ @Option(name = "--suffix", description = "The journal suffix (default amq)")
+ public String suffix = "amq";
+
+ @Option(name = "--file-size", description = "The journal size (default 10485760)")
+ public int size = 10485760;
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ super.execute(context);
+ try {
+ if (directory == null) {
+ directory = getFileConfiguration().getJournalDirectory();
+ }
+
+ exportJournal(directory, prefix, suffix, 2, size);
+ } catch (Exception e) {
+ treatError(e, "data", "encode");
+ }
+
+ return null;
+ }
+
+ private static void exportJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize) throws Exception {
+
+ exportJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, System.out);
+ }
+
+ public static void exportJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final String fileName) throws Exception {
+ try (FileOutputStream fileOutputStream = new FileOutputStream(fileName);
+ BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
+ PrintStream out = new PrintStream(bufferedOutputStream)) {
+ exportJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, out);
+ }
+ }
+
+ public static void exportJournal(final String directory,
+ final String journalPrefix,
+ final String journalSuffix,
+ final int minFiles,
+ final int fileSize,
+ final PrintStream out) throws Exception {
+ NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
+
+ JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
+
+ List<JournalFile> files = journal.orderFiles();
+
+ for (JournalFile file : files) {
+ out.println("#File," + file);
+
+ exportJournalFile(out, nio, file);
+ }
+ }
+
+ private static void exportJournalFile(final PrintStream out,
+ final SequentialFileFactory fileFactory,
+ final JournalFile file) throws Exception {
+ JournalImpl.readJournalFile(fileFactory, file, new JournalReaderCallback() {
+
+ @Override
+ public void onReadUpdateRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
+ out.println("operation@UpdateTX,txID@" + transactionID + "," + describeRecord(recordInfo));
+ }
+
+ @Override
+ public void onReadUpdateRecord(final RecordInfo recordInfo) throws Exception {
+ out.println("operation@Update," + describeRecord(recordInfo));
+ }
+
+ @Override
+ public void onReadRollbackRecord(final long transactionID) throws Exception {
+ out.println("operation@Rollback,txID@" + transactionID);
+ }
+
+ @Override
+ public void onReadPrepareRecord(final long transactionID,
+ final byte[] extraData,
+ final int numberOfRecords) throws Exception {
+ out.println("operation@Prepare,txID@" + transactionID +
+ ",numberOfRecords@" +
+ numberOfRecords +
+ ",extraData@" +
+ encode(extraData));
+ }
+
+ @Override
+ public void onReadDeleteRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
+ out.println("operation@DeleteRecordTX,txID@" + transactionID +
+ "," +
+ describeRecord(recordInfo));
+ }
+
+ @Override
+ public void onReadDeleteRecord(final long recordID) throws Exception {
+ out.println("operation@DeleteRecord,id@" + recordID);
+ }
+
+ @Override
+ public void onReadCommitRecord(final long transactionID, final int numberOfRecords) throws Exception {
+ out.println("operation@Commit,txID@" + transactionID + ",numberOfRecords@" + numberOfRecords);
+ }
+
+ @Override
+ public void onReadAddRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
+ out.println("operation@AddRecordTX,txID@" + transactionID + "," + describeRecord(recordInfo));
+ }
+
+ @Override
+ public void onReadAddRecord(final RecordInfo recordInfo) throws Exception {
+ out.println("operation@AddRecord," + describeRecord(recordInfo));
+ }
+
+ @Override
+ public void markAsDataFile(final JournalFile file) {
+ }
+ });
+ }
+
+ private static String describeRecord(final RecordInfo recordInfo) {
+ return "id@" + recordInfo.id +
+ ",userRecordType@" +
+ recordInfo.userRecordType +
+ ",length@" +
+ recordInfo.data.length +
+ ",isUpdate@" +
+ recordInfo.isUpdate +
+ ",compactCount@" +
+ recordInfo.compactCount +
+ ",data@" +
+ encode(recordInfo.data);
+ }
+
+ private static String encode(final byte[] data) {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/PerfJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/PerfJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/PerfJournal.java
new file mode 100644
index 0000000..3805de6
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/journal/PerfJournal.java
@@ -0,0 +1,92 @@
+/**
+ * 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 org.apache.activemq.artemis.cli.commands.tools.journal;
+
+import java.text.DecimalFormat;
+
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
+import org.apache.activemq.artemis.cli.commands.ActionContext;
+import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
+import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
+import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
+import org.apache.activemq.artemis.core.server.JournalType;
+
+@Command(name = "perf-journal", description = "Calculates the journal-buffer-timeout you should use with the current data folder")
+public class PerfJournal extends LockAbstract {
+
+
+ @Option(name = "--block-size", description = "The block size for each write (default 4096)")
+ public int size = 4 * 1024;
+
+ @Option(name = "--writes", description = "The number of writes to be performed (default 250)")
+ public int writes = 250;
+
+ @Option(name = "--tries", description = "The number of tries for the test (default 5)")
+ public int tries = 5;
+
+ @Option(name = "--no-sync", description = "Disable sync")
+ public boolean nosyncs = false;
+
+ @Option(name = "--sync", description = "Enable syncs")
+ public boolean syncs = false;
+
+ @Option(name = "--journal-type", description = "Journal Type to be used (default from broker.xml)")
+ public String journalType = null;
+
+
+ @Override
+ public Object execute(ActionContext context) throws Exception {
+ super.execute(context);
+
+ FileConfiguration fileConfiguration = getFileConfiguration();
+
+ if (nosyncs) {
+ fileConfiguration.setJournalDatasync(false);
+ } else if (syncs) {
+ fileConfiguration.setJournalDatasync(true);
+ }
+
+
+ if (journalType != null) {
+ fileConfiguration.setJournalType(JournalType.getType(journalType));
+ }
+
+ System.out.println("");
+ System.out.println("Auto tuning journal ...");
+
+ System.out.println("Performing " + tries + " tests writing " + writes + " blocks of " + size + " on each test, sync=" + fileConfiguration.isJournalDatasync() + " with journalType = " + fileConfiguration.getJournalType());
+
+ fileConfiguration.getJournalLocation().mkdirs();
+
+ long time = SyncCalculation.syncTest(fileConfiguration.getJournalLocation(), size, writes, tries, verbose, fileConfiguration.isJournalDatasync(), fileConfiguration.getJournalType());
+
+ long nanosecondsWait = SyncCalculation.toNanos(time, writes, verbose);
+ double writesPerMillisecond = (double) writes / (double) time;
+
+ String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond);
+
+ context.out.println("Your system can execute " + writesPerMillisecondStr + " syncs per millisecond");
+ context.out.println("Your journal-buffer-timeout should be:" + nanosecondsWait);
+ context.out.println("You should use this following configuration:");
+ context.out.println();
+ context.out.println("<journal-buffer-timeout>" + nanosecondsWait + "</journal-buffer-timeout>");
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataConstants.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataConstants.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataConstants.java
new file mode 100644
index 0000000..61c6d6b
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/xml/XmlDataConstants.java
@@ -0,0 +1,81 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.tools.xml;
+
+/**
+ * The constants shared by <code>org.apache.activemq.tools.XmlDataImporter</code> and
+ * <code>org.apache.activemq.tools.XmlDataExporter</code>.
+ */
+public final class XmlDataConstants {
+
+ private XmlDataConstants() {
+ // Utility
+ }
+
+ static final String XML_VERSION = "1.0";
+ static final String DOCUMENT_PARENT = "activemq-journal";
+ static final String BINDINGS_PARENT = "bindings";
+
+ static final String QUEUE_BINDINGS_CHILD = "queue-binding";
+ static final String QUEUE_BINDING_ADDRESS = "address";
+ static final String QUEUE_BINDING_FILTER_STRING = "filter-string";
+ static final String QUEUE_BINDING_NAME = "name";
+ static final String QUEUE_BINDING_ID = "id";
+ static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type";
+
+ static final String ADDRESS_BINDINGS_CHILD = "address-binding";
+ static final String ADDRESS_BINDING_NAME = "name";
+ static final String ADDRESS_BINDING_ID = "id";
+ static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types";
+
+ static final String MESSAGES_PARENT = "messages";
+ static final String MESSAGES_CHILD = "message";
+ static final String MESSAGE_ID = "id";
+ static final String MESSAGE_PRIORITY = "priority";
+ static final String MESSAGE_EXPIRATION = "expiration";
+ static final String MESSAGE_TIMESTAMP = "timestamp";
+ static final String DEFAULT_TYPE_PRETTY = "default";
+ static final String BYTES_TYPE_PRETTY = "bytes";
+ static final String MAP_TYPE_PRETTY = "map";
+ static final String OBJECT_TYPE_PRETTY = "object";
+ static final String STREAM_TYPE_PRETTY = "stream";
+ static final String TEXT_TYPE_PRETTY = "text";
+ static final String MESSAGE_TYPE = "type";
+ static final String MESSAGE_IS_LARGE = "isLarge";
+ static final String MESSAGE_USER_ID = "user-id";
+ static final String MESSAGE_BODY = "body";
+ static final String PROPERTIES_PARENT = "properties";
+ static final String PROPERTIES_CHILD = "property";
+ static final String PROPERTY_NAME = "name";
+ static final String PROPERTY_VALUE = "value";
+ static final String PROPERTY_TYPE = "type";
+ static final String QUEUES_PARENT = "queues";
+ static final String QUEUES_CHILD = "queue";
+ public static final String QUEUE_NAME = "name";
+ static final String PROPERTY_TYPE_BOOLEAN = "boolean";
+ static final String PROPERTY_TYPE_BYTE = "byte";
+ static final String PROPERTY_TYPE_BYTES = "bytes";
+ static final String PROPERTY_TYPE_SHORT = "short";
+ static final String PROPERTY_TYPE_INTEGER = "integer";
+ static final String PROPERTY_TYPE_LONG = "long";
+ static final String PROPERTY_TYPE_FLOAT = "float";
+ static final String PROPERTY_TYPE_DOUBLE = "double";
+ static final String PROPERTY_TYPE_STRING = "string";
+ static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
+
+ static final String NULL = "_AMQ_NULL";
+}
\ No newline at end of file
[5/6] activemq-artemis git commit: ARTEMIS-904 Remove cyclic
dependencies from artemis-cli
Posted by jb...@apache.org.
ARTEMIS-904 Remove cyclic dependencies from artemis-cli
move classes and methods to their correct location to avoid cyclic dependencies between packages and classes.
ARTEMIS-904 Remove cyclic dependencies from artemis-cli
move classes and methods to their correct location to avoid cyclic dependencies between packages and classes.
ARTEMIS-904 Remove cyclic dependencies from artemis-cli
move classes and methods to their correct location to avoid cyclic dependencies between packages and classes.
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/f82623a2
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/f82623a2
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/f82623a2
Branch: refs/heads/master
Commit: f82623a20c3bcd7acdfd01f7ee75b1de4a7d2e96
Parents: eeca06d
Author: Bennet Schulz <ma...@bennet-schulz.de>
Authored: Thu Apr 27 15:36:38 2017 +0200
Committer: Justin Bertram <jb...@apache.org>
Committed: Thu May 4 10:25:06 2017 -0500
----------------------------------------------------------------------
.../apache/activemq/artemis/cli/Artemis.java | 36 +-
.../artemis/cli/commands/ActionAbstract.java | 1 -
.../artemis/cli/commands/Configurable.java | 2 +-
.../activemq/artemis/cli/commands/Create.java | 274 ++------
.../artemis/cli/commands/HelpAction.java | 1 -
.../artemis/cli/commands/InputAbstract.java | 7 +-
.../activemq/artemis/cli/commands/Mask.java | 9 +-
.../artemis/cli/commands/OptionsUtil.java | 65 ++
.../activemq/artemis/cli/commands/Run.java | 10 +-
.../cli/commands/address/HelpAddress.java | 2 +-
.../artemis/cli/commands/messages/Browse.java | 1 -
.../artemis/cli/commands/messages/Consumer.java | 1 -
.../cli/commands/messages/ConsumerThread.java | 320 +++++++++
.../artemis/cli/commands/messages/Producer.java | 1 -
.../cli/commands/messages/ProducerThread.java | 344 +++++++++
.../artemis/cli/commands/queue/HelpQueue.java | 2 +-
.../cli/commands/tools/CompactJournal.java | 65 --
.../cli/commands/tools/DecodeJournal.java | 318 ---------
.../cli/commands/tools/EncodeJournal.java | 208 ------
.../artemis/cli/commands/tools/HelpData.java | 2 +-
.../cli/commands/tools/LockAbstract.java | 19 +-
.../artemis/cli/commands/tools/PerfJournal.java | 92 ---
.../artemis/cli/commands/tools/PrintData.java | 37 +-
.../cli/commands/tools/XmlDataConstants.java | 129 ----
.../cli/commands/tools/XmlDataExporter.java | 626 -----------------
.../cli/commands/tools/XmlDataExporterUtil.java | 107 ---
.../cli/commands/tools/XmlDataImporter.java | 690 -------------------
.../commands/tools/journal/CompactJournal.java | 66 ++
.../commands/tools/journal/DecodeJournal.java | 296 ++++++++
.../commands/tools/journal/EncodeJournal.java | 191 +++++
.../cli/commands/tools/journal/PerfJournal.java | 92 +++
.../commands/tools/xml/XmlDataConstants.java | 81 +++
.../cli/commands/tools/xml/XmlDataExporter.java | 627 +++++++++++++++++
.../commands/tools/xml/XmlDataExporterUtil.java | 104 +++
.../cli/commands/tools/xml/XmlDataImporter.java | 614 +++++++++++++++++
.../artemis/cli/commands/user/AddUser.java | 3 +-
.../commands/user/FileBasedSecStoreConfig.java | 222 ++++++
.../artemis/cli/commands/user/HelpUser.java | 10 +-
.../artemis/cli/commands/user/ListUser.java | 3 +-
.../cli/commands/user/PasswordAction.java | 2 +-
.../artemis/cli/commands/user/RemoveUser.java | 3 +-
.../artemis/cli/commands/user/ResetUser.java | 3 +-
.../artemis/cli/commands/user/UserAction.java | 23 +-
.../cli/commands/util/ConsumerThread.java | 320 ---------
.../cli/commands/util/ProducerThread.java | 344 ---------
.../artemis/cli/factory/BrokerFactory.java | 73 ++
.../cli/factory/BrokerFactoryHandler.java | 26 +
.../artemis/cli/factory/BrokerHandler.java | 26 +
.../artemis/cli/factory/FileBrokerHandler.java | 30 +
.../factory/security/JaasSecurityHandler.java | 31 +
.../cli/factory/security/SecurityHandler.java | 25 +
.../security/SecurityManagerFactory.java | 35 +
.../factory/xml/XmlBrokerFactoryHandler.java | 37 +
.../activemq/artemis/factory/BrokerFactory.java | 82 ---
.../artemis/factory/BrokerFactoryHandler.java | 28 -
.../activemq/artemis/factory/BrokerHandler.java | 26 -
.../artemis/factory/FileBrokerHandler.java | 30 -
.../artemis/factory/JaasSecurityHandler.java | 32 -
.../artemis/factory/SecurityHandler.java | 25 -
.../artemis/factory/SecurityManagerFactory.java | 37 -
.../factory/XmlBrokerFactoryHandler.java | 41 --
.../artemis/integration/FileBroker.java | 4 +-
.../artemis/util/FileBasedSecStoreConfig.java | 222 ------
.../activemq/artemis/util/OptionsUtil.java | 67 --
.../activemq/artemis/util/ServerUtil.java | 8 +-
.../artemis/broker/security/jaas-security | 2 +-
.../apache/activemq/artemis/broker/server/file | 2 +-
.../org/apache/activemq/artemis/broker/xml | 2 +-
.../persistence/ExportFormatTest.java | 4 +-
.../persistence/XmlImportExportTest.java | 6 +-
.../journal/XmlImportExportStressTest.java | 4 +-
.../core/journal/impl/JournalImplTestBase.java | 4 +-
72 files changed, 3466 insertions(+), 3816 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
index 2821a3e..45e1dfd 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
@@ -17,8 +17,6 @@
package org.apache.activemq.artemis.cli;
import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.util.List;
import io.airlift.airline.Cli;
@@ -37,22 +35,22 @@ import org.apache.activemq.artemis.cli.commands.address.DeleteAddress;
import org.apache.activemq.artemis.cli.commands.address.HelpAddress;
import org.apache.activemq.artemis.cli.commands.address.ShowAddress;
import org.apache.activemq.artemis.cli.commands.address.UpdateAddress;
+import org.apache.activemq.artemis.cli.commands.messages.Browse;
+import org.apache.activemq.artemis.cli.commands.messages.Consumer;
+import org.apache.activemq.artemis.cli.commands.messages.Producer;
import org.apache.activemq.artemis.cli.commands.migration1x.Migrate1X;
import org.apache.activemq.artemis.cli.commands.queue.CreateQueue;
import org.apache.activemq.artemis.cli.commands.queue.DeleteQueue;
import org.apache.activemq.artemis.cli.commands.queue.HelpQueue;
-import org.apache.activemq.artemis.cli.commands.messages.Browse;
-import org.apache.activemq.artemis.cli.commands.messages.Consumer;
-import org.apache.activemq.artemis.cli.commands.messages.Producer;
import org.apache.activemq.artemis.cli.commands.queue.UpdateQueue;
-import org.apache.activemq.artemis.cli.commands.tools.CompactJournal;
-import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal;
-import org.apache.activemq.artemis.cli.commands.tools.EncodeJournal;
import org.apache.activemq.artemis.cli.commands.tools.HelpData;
import org.apache.activemq.artemis.cli.commands.tools.PrintData;
-import org.apache.activemq.artemis.cli.commands.tools.PerfJournal;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataExporter;
-import org.apache.activemq.artemis.cli.commands.tools.XmlDataImporter;
+import org.apache.activemq.artemis.cli.commands.tools.journal.CompactJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.DecodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.EncodeJournal;
+import org.apache.activemq.artemis.cli.commands.tools.journal.PerfJournal;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataExporter;
+import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataImporter;
import org.apache.activemq.artemis.cli.commands.user.AddUser;
import org.apache.activemq.artemis.cli.commands.user.HelpUser;
import org.apache.activemq.artemis.cli.commands.user.ListUser;
@@ -126,7 +124,7 @@ public class Artemis {
* This method is used to validate exception returns.
* Useful on test cases
*/
- public static Object internalExecute(File artemisHome, File artemisInstance, String[] args) throws Exception {
+ private static Object internalExecute(File artemisHome, File artemisInstance, String[] args) throws Exception {
return internalExecute(artemisHome, artemisInstance, args, ActionContext.system());
}
@@ -174,18 +172,4 @@ public class Artemis {
return builder;
}
- public static void printBanner() throws Exception {
- copy(Artemis.class.getResourceAsStream("banner.txt"), System.out);
- }
-
- private static long copy(InputStream in, OutputStream out) throws Exception {
- byte[] buffer = new byte[1024];
- int len = in.read(buffer);
- while (len != -1) {
- out.write(buffer, 0, len);
- len = in.read(buffer);
- }
- return len;
- }
-
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionAbstract.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionAbstract.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionAbstract.java
index ce90c23..2037d01 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionAbstract.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/ActionAbstract.java
@@ -20,7 +20,6 @@ import java.io.File;
import java.net.URI;
import io.airlift.airline.Option;
-import org.apache.activemq.artemis.util.OptionsUtil;
public abstract class ActionAbstract implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
index 316b2c2..9046c8f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
@@ -26,10 +26,10 @@ import io.airlift.airline.Option;
import io.airlift.airline.model.CommandGroupMetadata;
import io.airlift.airline.model.CommandMetadata;
import io.airlift.airline.model.GlobalMetadata;
+import org.apache.activemq.artemis.cli.factory.BrokerFactory;
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
import org.apache.activemq.artemis.dto.BrokerDTO;
-import org.apache.activemq.artemis.factory.BrokerFactory;
import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger;
import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 66bffe2..feb23dd 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -84,9 +84,9 @@ public class Create extends InputAbstract {
public static final String ETC_ARTEMIS_ROLES_PROPERTIES = "etc/artemis-roles.properties";
public static final String ETC_ARTEMIS_USERS_PROPERTIES = "etc/artemis-users.properties";
- public static final String ETC_LOGIN_CONFIG = "etc/login.config";
- public static final String ETC_LOGIN_CONFIG_WITH_GUEST = "etc/login-with-guest.config";
- public static final String ETC_LOGIN_CONFIG_WITHOUT_GUEST = "etc/login-without-guest.config";
+ private static final String ETC_LOGIN_CONFIG = "etc/login.config";
+ private static final String ETC_LOGIN_CONFIG_WITH_GUEST = "etc/login-with-guest.config";
+ private static final String ETC_LOGIN_CONFIG_WITHOUT_GUEST = "etc/login-without-guest.config";
public static final String ETC_REPLICATED_SETTINGS_TXT = "etc/replicated-settings.txt";
public static final String ETC_SHARED_STORE_SETTINGS_TXT = "etc/shared-store-settings.txt";
public static final String ETC_CLUSTER_SECURITY_SETTINGS_TXT = "etc/cluster-security-settings.txt";
@@ -105,213 +105,162 @@ public class Create extends InputAbstract {
public static final String ETC_GLOBAL_MAX_DEFAULT_TXT = "etc/global-max-default.txt";
@Arguments(description = "The instance directory to hold the broker's configuration and data. Path must be writable.", required = true)
- File directory;
+ private File directory;
@Option(name = "--host", description = "The host name of the broker (Default: 0.0.0.0 or input if clustered)")
- String host;
+ private String host;
@Option(name = "--http-host", description = "The host name to use for embedded web server (Default: localhost)")
- String httpHost = HTTP_HOST;
+ private String httpHost = HTTP_HOST;
@Option(name = "--ping", description = "A comma separated string to be passed on to the broker config as network-check-list. The broker will shutdown when all these addresses are unreachable.")
- String ping;
+ private String ping;
@Option(name = "--default-port", description = "The port number to use for the main 'artemis' acceptor (Default: 61616)")
- int defaultPort = DEFAULT_PORT;
+ private int defaultPort = DEFAULT_PORT;
@Option(name = "--http-port", description = "The port number to use for embedded web server (Default: 8161)")
- int httpPort = HTTP_PORT;
+ private int httpPort = HTTP_PORT;
@Option(name = "--ssl-key", description = "The key store path for embedded web server")
- String sslKey;
+ private String sslKey;
@Option(name = "--ssl-key-password", description = "The key store password")
- String sslKeyPassword;
+ private String sslKeyPassword;
@Option(name = "--use-client-auth", description = "If the embedded server requires client authentication")
- boolean useClientAuth;
+ private boolean useClientAuth;
@Option(name = "--ssl-trust", description = "The trust store path in case of client authentication")
- String sslTrust;
+ private String sslTrust;
@Option(name = "--ssl-trust-password", description = "The trust store password")
- String sslTrustPassword;
+ private String sslTrustPassword;
@Option(name = "--name", description = "The name of the broker (Default: same as host)")
- String name;
+ private String name;
@Option(name = "--port-offset", description = "Off sets the ports of every acceptor")
- int portOffset;
+ private int portOffset;
@Option(name = "--force", description = "Overwrite configuration at destination directory")
- boolean force;
+ private boolean force;
@Option(name = "--home", description = "Directory where ActiveMQ Artemis is installed")
- File home;
+ private File home;
@Option(name = "--data", description = "Directory where ActiveMQ Data is used. Paths are relative to artemis.instance")
- String data = "./data";
+ private String data = "./data";
@Option(name = "--clustered", description = "Enable clustering")
- boolean clustered = false;
+ private boolean clustered = false;
@Option(name = "--max-hops", description = "Number of hops on the cluster configuration")
- int maxHops = 0;
+ private int maxHops = 0;
@Option(name = "--message-load-balancing", description = "Load balancing policy on cluster. [ON_DEMAND (default) | STRICT | OFF]")
- MessageLoadBalancingType messageLoadBalancing = MessageLoadBalancingType.ON_DEMAND;
+ private MessageLoadBalancingType messageLoadBalancing = MessageLoadBalancingType.ON_DEMAND;
@Option(name = "--replicated", description = "Enable broker replication")
- boolean replicated = false;
+ private boolean replicated = false;
@Option(name = "--shared-store", description = "Enable broker shared store")
- boolean sharedStore = false;
+ private boolean sharedStore = false;
@Option(name = "--slave", description = "Valid for shared store or replication: this is a slave server?")
- boolean slave;
+ private boolean slave;
@Option(name = "--failover-on-shutdown", description = "Valid for shared store: will shutdown trigger a failover? (Default: false)")
- boolean failoverOnShutodwn;
+ private boolean failoverOnShutodwn;
@Option(name = "--cluster-user", description = "The cluster user to use for clustering. (Default: input)")
- String clusterUser = null;
+ private String clusterUser = null;
@Option(name = "--cluster-password", description = "The cluster password to use for clustering. (Default: input)")
- String clusterPassword = null;
+ private String clusterPassword = null;
@Option(name = "--encoding", description = "The encoding that text files should use")
- String encoding = "UTF-8";
+ private String encoding = "UTF-8";
@Option(name = "--java-options", description = "Extra java options to be passed to the profile")
- String javaOptions = "";
+ private String javaOptions = "";
@Option(name = "--allow-anonymous", description = "Enables anonymous configuration on security, opposite of --require-login (Default: input)")
- Boolean allowAnonymous = null;
+ private Boolean allowAnonymous = null;
@Option(name = "--require-login", description = "This will configure security to require user / password, opposite of --allow-anonymous")
- Boolean requireLogin = null;
+ private Boolean requireLogin = null;
@Option(name = "--paging", description = "Page messages to disk when address becomes full, opposite of --blocking (Default: true)")
- Boolean paging;
+ private Boolean paging;
@Option(name = "--blocking", description = "Block producers when address becomes full, opposite of --paging (Default: false)")
- Boolean blocking;
+ private Boolean blocking;
@Option(name = "--no-autotune", description = "Disable auto tuning on the journal.")
- boolean noAutoTune;
+ private boolean noAutoTune;
@Option(name = "--no-autocreate", description = "Disable Auto create addresses.")
- Boolean noAutoCreate;
+ private Boolean noAutoCreate;
@Option(name = "--autocreate", description = "Auto create addresses. (default: true)")
- Boolean autoCreate;
+ private Boolean autoCreate;
@Option(name = "--user", description = "The username (Default: input)")
- String user;
+ private String user;
@Option(name = "--password", description = "The user's password (Default: input)")
- String password;
+ private String password;
@Option(name = "--role", description = "The name for the role created (Default: amq)")
- String role = "amq";
+ private String role = "amq";
@Option(name = "--no-web", description = "Remove the web-server definition from bootstrap.xml")
- boolean noWeb;
+ private boolean noWeb;
@Option(name = "--queues", description = "Comma separated list of queues.")
- String queues;
+ private String queues;
@Option(name = "--addresses", description = "Comma separated list of addresses ")
- String addresses;
+ private String addresses;
@Option(name = "--aio", description = "Sets the journal as asyncio.")
- boolean aio;
+ private boolean aio;
@Option(name = "--nio", description = "Sets the journal as nio.")
- boolean nio;
+ private boolean nio;
@Option(name = "--mapped", description = "Sets the journal as mapped.")
- boolean mapped;
+ private boolean mapped;
// this is used by the setupJournalType method
private JournalType journalType;
@Option(name = "--disable-persistence", description = "Disable message persistence to the journal")
- boolean disablePersistence;
+ private boolean disablePersistence;
@Option(name = "--no-amqp-acceptor", description = "Disable the AMQP specific acceptor.")
- boolean noAmqpAcceptor;
+ private boolean noAmqpAcceptor;
@Option(name = "--no-mqtt-acceptor", description = "Disable the MQTT specific acceptor.")
- boolean noMqttAcceptor;
+ private boolean noMqttAcceptor;
@Option(name = "--no-stomp-acceptor", description = "Disable the STOMP specific acceptor.")
- boolean noStompAcceptor;
+ private boolean noStompAcceptor;
@Option(name = "--no-hornetq-acceptor", description = "Disable the HornetQ specific acceptor.")
- boolean noHornetQAcceptor;
+ private boolean noHornetQAcceptor;
@Option(name = "--no-fsync", description = "Disable usage of fdatasync (channel.force(false) from java nio) on the journal")
- boolean noJournalSync;
+ private boolean noJournalSync;
@Option(name = "--global-max-size", description = "Maximum amount of memory which message data may consume (Default: Undefined, half of the system's memory)")
- String globalMaxSize;
+ private String globalMaxSize;
- boolean IS_WINDOWS;
+ private boolean IS_WINDOWS;
+ private boolean IS_CYGWIN;
- boolean IS_CYGWIN;
-
- public int getMaxHops() {
- return maxHops;
- }
-
- public void setMaxHops(int maxHops) {
- this.maxHops = maxHops;
- }
-
- public boolean isNoWeb() {
- return noWeb;
- }
-
- public void setNoWeb(boolean noWeb) {
- this.noWeb = noWeb;
- }
-
- public int getPortOffset() {
- return portOffset;
- }
-
- public void setPortOffset(int portOffset) {
- this.portOffset = portOffset;
- }
-
- public MessageLoadBalancingType getMessageLoadBalancing() {
- return messageLoadBalancing;
- }
-
- public void setMessageLoadBalancing(MessageLoadBalancingType messageLoadBalancing) {
- this.messageLoadBalancing = messageLoadBalancing;
- }
-
- public Boolean getAutoCreate() {
- return autoCreate;
- }
-
- public Create setAutoCreate(Boolean autoCreate) {
- this.autoCreate = autoCreate;
- return this;
- }
-
- public Boolean getNoAutoCreate() {
- return noAutoCreate;
- }
-
- public Create setNoAutoCreate(Boolean noAutoCreate) {
- this.noAutoCreate = noAutoCreate;
- return this;
- }
-
- public boolean isAutoCreate() {
+ private boolean isAutoCreate() {
if (autoCreate == null) {
if (noAutoCreate != null) {
autoCreate = !noAutoCreate.booleanValue();
@@ -325,14 +274,6 @@ public class Create extends InputAbstract {
return autoCreate;
}
- public String getJavaOptions() {
- return javaOptions;
- }
-
- public void setJavaOptions(String javaOptions) {
- this.javaOptions = javaOptions;
- }
-
public File getInstance() {
return directory;
}
@@ -348,7 +289,7 @@ public class Create extends InputAbstract {
return host;
}
- public String getHostForClustered() {
+ private String getHostForClustered() {
if (getHost().equals("0.0.0.0")) {
host = input("--host", "Host " + host + " is not valid for clustering, please provide a valid IP or hostname", "localhost");
}
@@ -379,14 +320,6 @@ public class Create extends InputAbstract {
this.home = home;
}
- public boolean isClustered() {
- return clustered;
- }
-
- public void setClustered(boolean clustered) {
- this.clustered = clustered;
- }
-
public boolean isReplicated() {
return replicated;
}
@@ -399,10 +332,6 @@ public class Create extends InputAbstract {
return sharedStore;
}
- public void setSharedStore(boolean sharedStore) {
- this.sharedStore = sharedStore;
- }
-
public String getEncoding() {
return encoding;
}
@@ -419,50 +348,42 @@ public class Create extends InputAbstract {
this.data = data;
}
- public String getClusterUser() {
+ private String getClusterUser() {
if (clusterUser == null) {
clusterUser = input("--cluster-user", "Please provide the username:", "cluster-admin");
}
return clusterUser;
}
- public void setClusterUser(String clusterUser) {
- this.clusterUser = clusterUser;
- }
-
- public String getClusterPassword() {
+ private String getClusterPassword() {
if (clusterPassword == null) {
clusterPassword = inputPassword("--cluster-password", "Please enter the password:", "password-admin");
}
return clusterPassword;
}
- public String getSslKeyPassword() {
+ private String getSslKeyPassword() {
if (sslKeyPassword == null) {
sslKeyPassword = inputPassword("--ssl-key-password", "Please enter the keystore password:", "password");
}
return sslKeyPassword;
}
- public String getSslTrust() {
+ private String getSslTrust() {
if (sslTrust == null) {
sslTrust = input("--ssl-trust", "Please enter the trust store path:", "/etc/truststore.jks");
}
return sslTrust;
}
- public String getSslTrustPassword() {
+ private String getSslTrustPassword() {
if (sslTrustPassword == null) {
sslTrustPassword = inputPassword("--ssl-key-password", "Please enter the keystore password:", "password");
}
return sslTrustPassword;
}
- public void setClusterPassword(String clusterPassword) {
- this.clusterPassword = clusterPassword;
- }
-
- public boolean isAllowAnonymous() {
+ private boolean isAllowAnonymous() {
if (allowAnonymous == null) {
allowAnonymous = inputBoolean("--allow-anonymous | --require-login", "Allow anonymous access?", true);
}
@@ -473,21 +394,6 @@ public class Create extends InputAbstract {
return paging;
}
- public void setAllowAnonymous(boolean allowAnonymous) {
- this.allowAnonymous = Boolean.valueOf(allowAnonymous);
- }
-
- public Boolean getRequireLogin() {
- if (requireLogin == null) {
- requireLogin = !isAllowAnonymous();
- }
- return requireLogin;
- }
-
- public void setRequireLogin(Boolean requireLogin) {
- this.requireLogin = requireLogin;
- }
-
public String getPassword() {
if (password == null) {
@@ -522,45 +428,18 @@ public class Create extends InputAbstract {
this.role = role;
}
- public String getGlobalMaxSize() {
- return globalMaxSize;
- }
- public void setGlobalMaxSize(String globalMaxSize) {
- this.globalMaxSize = globalMaxSize;
- }
-
- public boolean isSlave() {
+ private boolean isSlave() {
return slave;
}
- public void setSlave(boolean slave) {
- this.slave = slave;
- }
-
- public boolean isFailoverOnShutodwn() {
+ private boolean isFailoverOnShutodwn() {
return failoverOnShutodwn;
}
- public void setFailoverOnShutodwn(boolean failoverOnShutodwn) {
- this.failoverOnShutodwn = failoverOnShutodwn;
- }
-
- public Boolean getAllowAnonymous() {
- return allowAnonymous;
- }
-
- public void setAllowAnonymous(Boolean allowAnonymous) {
- this.allowAnonymous = allowAnonymous;
- }
-
- public boolean isDisablePersistence() {
+ private boolean isDisablePersistence() {
return disablePersistence;
}
- public void setDisablePersistence(boolean disablePersistence) {
- this.disablePersistence = disablePersistence;
- }
-
@Override
public Object execute(ActionContext context) throws Exception {
this.checkDirectory();
@@ -589,6 +468,7 @@ public class Create extends InputAbstract {
throw new RuntimeException(String.format("The path '%s' is not writable.", directory));
}
}
+
public Object run(ActionContext context) throws Exception {
IS_WINDOWS = System.getProperty("os.name").toLowerCase().trim().startsWith("win");
@@ -860,7 +740,6 @@ public class Create extends InputAbstract {
}
}
-
private static int countBoolean(boolean...b) {
int count = 0;
@@ -890,23 +769,6 @@ public class Create extends InputAbstract {
}
/**
- * It will create the jms configurations
- */
- private void applyJMSObjects(HashMap<String, String> filters) {
- StringWriter writer = new StringWriter();
- PrintWriter printWriter = new PrintWriter(writer);
- printWriter.println();
-
- for (String str : getQueueList()) {
- printWriter.println(" <queue name=\"" + str + "\"/>");
- }
- for (String str : getAddressList()) {
- printWriter.println(" <topic name=\"" + str + "\"/>");
- }
- filters.put("${jms-list.settings}", writer.toString());
- }
-
- /**
* It will create the address and queue configurations
*/
private void applyAddressesAndQueues(HashMap<String, String> filters) {
@@ -1004,7 +866,7 @@ public class Create extends InputAbstract {
}
}
- String path(String value, boolean unixPaths) throws IOException {
+ private String path(String value, boolean unixPaths) throws IOException {
return path(new File(value), unixPaths);
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/HelpAction.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/HelpAction.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/HelpAction.java
index a154494..ebbacdd 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/HelpAction.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/HelpAction.java
@@ -19,7 +19,6 @@ package org.apache.activemq.artemis.cli.commands;
import java.io.File;
import io.airlift.airline.Help;
-import org.apache.activemq.artemis.util.OptionsUtil;
public class HelpAction extends Help implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InputAbstract.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InputAbstract.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InputAbstract.java
index 4d1fe35..d4535be 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InputAbstract.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InputAbstract.java
@@ -37,15 +37,10 @@ public class InputAbstract extends ActionAbstract {
@Option(name = "--silent", description = "It will disable all the inputs, and it would make a best guess for any required input")
private boolean silentInput = false;
- public boolean isSilentInput() {
+ private boolean isSilentInput() {
return silentInput || !inputEnabled;
}
- public void setSilentInput(boolean silentInput) {
- this.silentInput = silentInput;
- }
-
-
protected boolean inputBoolean(String propertyName, String prompt, boolean silentDefault) {
if (isSilentInput()) {
return silentDefault;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Mask.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Mask.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Mask.java
index d90536e..e8a778f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Mask.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Mask.java
@@ -16,17 +16,16 @@
*/
package org.apache.activemq.artemis.cli.commands;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
-import org.apache.activemq.artemis.util.OptionsUtil;
import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
@Command(name = "mask", description = "mask a password and print it out")
public class Mask implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/OptionsUtil.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/OptionsUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/OptionsUtil.java
new file mode 100644
index 0000000..926236a
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/OptionsUtil.java
@@ -0,0 +1,65 @@
+/**
+ * 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 org.apache.activemq.artemis.cli.commands;
+
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
+
+import io.airlift.airline.Option;
+
+public class OptionsUtil {
+
+ private static void findAllOptions(Set<String> options, Class<? extends Action> command) {
+ for (Field field : command.getDeclaredFields()) {
+ if (field.isAnnotationPresent(Option.class)) {
+ Option annotation = field.getAnnotation(Option.class);
+ String[] names = annotation.name();
+ for (String n : names) {
+ options.add(n);
+ }
+ }
+ }
+ Class parent = command.getSuperclass();
+ if (Action.class.isAssignableFrom(parent)) {
+ findAllOptions(options, parent);
+ }
+ }
+
+ private static Set<String> findCommandOptions(Class<? extends Action> command) {
+ Set<String> options = new HashSet<>();
+ findAllOptions(options, command);
+
+ return options;
+ }
+
+ public static void checkCommandOptions(Class<? extends Action> cmdClass, String[] options) throws InvalidOptionsError {
+ Set<String> definedOptions = OptionsUtil.findCommandOptions(cmdClass);
+ for (String opt : options) {
+ if (opt.startsWith("--") && !"--".equals(opt.trim())) {
+ int index = opt.indexOf("=");
+ if (index > 0) {
+ opt = opt.substring(0, index);
+ }
+ if (!definedOptions.contains(opt)) {
+ throw new InvalidOptionsError("Found unexpected parameters: [" + opt + "]");
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
index 02478a1..a299b18 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
@@ -22,13 +22,13 @@ import java.util.TimerTask;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.Artemis;
import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
+import org.apache.activemq.artemis.cli.commands.tools.PrintData;
+import org.apache.activemq.artemis.cli.factory.BrokerFactory;
+import org.apache.activemq.artemis.cli.factory.security.SecurityManagerFactory;
import org.apache.activemq.artemis.components.ExternalComponent;
import org.apache.activemq.artemis.dto.BrokerDTO;
import org.apache.activemq.artemis.dto.ComponentDTO;
-import org.apache.activemq.artemis.factory.BrokerFactory;
-import org.apache.activemq.artemis.factory.SecurityManagerFactory;
import org.apache.activemq.artemis.integration.Broker;
import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
@@ -40,7 +40,7 @@ public class Run extends LockAbstract {
@Option(name = "--allow-kill", description = "This will allow the server to kill itself. Useful for tests (failover tests for instance)")
boolean allowKill;
- static boolean embedded = false;
+ private static boolean embedded = false;
public static final ReusableLatch latchRunning = new ReusableLatch(0);
@@ -60,7 +60,7 @@ public class Run extends LockAbstract {
public Object execute(ActionContext context) throws Exception {
super.execute(context);
- Artemis.printBanner();
+ PrintData.printBanner();
BrokerDTO broker = getBrokerDTO();
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/address/HelpAddress.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/address/HelpAddress.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/address/HelpAddress.java
index c89621e..0dcd20f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/address/HelpAddress.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/address/HelpAddress.java
@@ -25,7 +25,7 @@ import io.airlift.airline.Help;
import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
-import org.apache.activemq.artemis.util.OptionsUtil;
+import org.apache.activemq.artemis.cli.commands.OptionsUtil;
public class HelpAddress extends Help implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Browse.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Browse.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Browse.java
index 66336b3..5f03c82 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Browse.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Browse.java
@@ -24,7 +24,6 @@ import javax.jms.Session;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.cli.commands.util.ConsumerThread;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Consumer.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Consumer.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Consumer.java
index 1af9fac..5a2a8b6 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Consumer.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Consumer.java
@@ -24,7 +24,6 @@ import javax.jms.Session;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.cli.commands.util.ConsumerThread;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ConsumerThread.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ConsumerThread.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ConsumerThread.java
new file mode 100644
index 0000000..b69e618
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ConsumerThread.java
@@ -0,0 +1,320 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.messages;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import java.util.Enumeration;
+import java.util.concurrent.CountDownLatch;
+
+public class ConsumerThread extends Thread {
+
+ int messageCount = 1000;
+ int receiveTimeOut = 3000;
+ Destination destination;
+ Session session;
+ boolean durable;
+ boolean breakOnNull = true;
+ int sleep;
+ int batchSize;
+ boolean verbose;
+ boolean browse;
+
+ String filter;
+
+ int received = 0;
+ int transactions = 0;
+ boolean running = false;
+ CountDownLatch finished;
+ boolean bytesAsText;
+
+ public ConsumerThread(Session session, Destination destination, int threadNr) {
+ super("Consumer " + destination.toString() + ", thread=" + threadNr);
+ this.destination = destination;
+ this.session = session;
+ }
+
+ @Override
+ public void run() {
+ if (browse) {
+ browse();
+ } else {
+ consume();
+ }
+ }
+
+ public void browse() {
+ running = true;
+ QueueBrowser consumer = null;
+ String threadName = Thread.currentThread().getName();
+ System.out.println(threadName + " wait until " + messageCount + " messages are consumed");
+ try {
+ if (filter != null) {
+ consumer = session.createBrowser((Queue) destination, filter);
+ } else {
+ consumer = session.createBrowser((Queue) destination);
+ }
+ Enumeration<Message> enumBrowse = consumer.getEnumeration();
+
+ while (enumBrowse.hasMoreElements()) {
+ Message msg = enumBrowse.nextElement();
+ if (msg != null) {
+ System.out.println(threadName + " Received " + (msg instanceof TextMessage ? ((TextMessage) msg).getText() : msg.getJMSMessageID()));
+
+ if (verbose) {
+ System.out.println("..." + msg);
+ }
+ if (bytesAsText && (msg instanceof BytesMessage)) {
+ long length = ((BytesMessage) msg).getBodyLength();
+ byte[] bytes = new byte[(int) length];
+ ((BytesMessage) msg).readBytes(bytes);
+ System.out.println("Message:" + msg);
+ }
+ received++;
+
+ if (received >= messageCount) {
+ break;
+ }
+ } else {
+ break;
+ }
+
+ if (sleep > 0) {
+ Thread.sleep(sleep);
+ }
+
+ }
+
+ consumer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (finished != null) {
+ finished.countDown();
+ }
+ if (consumer != null) {
+ System.out.println(threadName + " Consumed: " + this.getReceived() + " messages");
+ try {
+ consumer.close();
+ } catch (JMSException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ System.out.println(threadName + " Consumer thread finished");
+ }
+
+ public void consume() {
+ running = true;
+ MessageConsumer consumer = null;
+ String threadName = Thread.currentThread().getName();
+ System.out.println(threadName + " wait until " + messageCount + " messages are consumed");
+ try {
+ if (durable && destination instanceof Topic) {
+ if (filter != null) {
+ consumer = session.createDurableSubscriber((Topic) destination, getName(), filter, false);
+ } else {
+ consumer = session.createDurableSubscriber((Topic) destination, getName());
+ }
+ } else {
+ if (filter != null) {
+ consumer = session.createConsumer(destination, filter);
+ } else {
+ consumer = session.createConsumer(destination);
+ }
+ }
+ while (running && received < messageCount) {
+ Message msg = consumer.receive(receiveTimeOut);
+ if (msg != null) {
+ System.out.println(threadName + " Received " + (msg instanceof TextMessage ? ((TextMessage) msg).getText() : msg.getJMSMessageID()));
+ if (verbose) {
+ System.out.println("..." + msg);
+ }
+ if (bytesAsText && (msg instanceof BytesMessage)) {
+ long length = ((BytesMessage) msg).getBodyLength();
+ byte[] bytes = new byte[(int) length];
+ ((BytesMessage) msg).readBytes(bytes);
+ System.out.println("Message:" + msg);
+ }
+ received++;
+ } else {
+ if (breakOnNull) {
+ break;
+ }
+ }
+
+ if (session.getTransacted()) {
+ if (batchSize > 0 && received > 0 && received % batchSize == 0) {
+ System.out.println(threadName + " Committing transaction: " + transactions++);
+ session.commit();
+ }
+ } else if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) {
+ if (batchSize > 0 && received > 0 && received % batchSize == 0) {
+ System.out.println("Acknowledging last " + batchSize + " messages; messages so far = " + received);
+ msg.acknowledge();
+ }
+ }
+ if (sleep > 0) {
+ Thread.sleep(sleep);
+ }
+
+ }
+
+ try {
+ session.commit();
+ } catch (Throwable ignored) {
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (finished != null) {
+ finished.countDown();
+ }
+ if (consumer != null) {
+ System.out.println(threadName + " Consumed: " + this.getReceived() + " messages");
+ try {
+ consumer.close();
+ } catch (JMSException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ System.out.println(threadName + " Consumer thread finished");
+ }
+
+ public int getReceived() {
+ return received;
+ }
+
+ public boolean isDurable() {
+ return durable;
+ }
+
+ public ConsumerThread setDurable(boolean durable) {
+ this.durable = durable;
+ return this;
+ }
+
+ public ConsumerThread setMessageCount(int messageCount) {
+ this.messageCount = messageCount;
+ return this;
+ }
+
+ public ConsumerThread setBreakOnNull(boolean breakOnNull) {
+ this.breakOnNull = breakOnNull;
+ return this;
+ }
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public ConsumerThread setBatchSize(int batchSize) {
+ this.batchSize = batchSize;
+ return this;
+ }
+
+ public int getMessageCount() {
+ return messageCount;
+ }
+
+ public boolean isBreakOnNull() {
+ return breakOnNull;
+ }
+
+ public int getReceiveTimeOut() {
+ return receiveTimeOut;
+ }
+
+ public ConsumerThread setReceiveTimeOut(int receiveTimeOut) {
+ this.receiveTimeOut = receiveTimeOut;
+ return this;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ public ConsumerThread setRunning(boolean running) {
+ this.running = running;
+ return this;
+ }
+
+ public int getSleep() {
+ return sleep;
+ }
+
+ public ConsumerThread setSleep(int sleep) {
+ this.sleep = sleep;
+ return this;
+ }
+
+ public CountDownLatch getFinished() {
+ return finished;
+ }
+
+ public ConsumerThread setFinished(CountDownLatch finished) {
+ this.finished = finished;
+ return this;
+ }
+
+ public boolean isBytesAsText() {
+ return bytesAsText;
+ }
+
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ public ConsumerThread setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ return this;
+ }
+
+ public ConsumerThread setBytesAsText(boolean bytesAsText) {
+ this.bytesAsText = bytesAsText;
+ return this;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public ConsumerThread setFilter(String filter) {
+ this.filter = filter;
+ return this;
+ }
+
+ public boolean isBrowse() {
+ return browse;
+ }
+
+ public ConsumerThread setBrowse(boolean browse) {
+ this.browse = browse;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Producer.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Producer.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Producer.java
index 4ec68ca..f7c11ae 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Producer.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/Producer.java
@@ -24,7 +24,6 @@ import javax.jms.Session;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.cli.commands.util.ProducerThread;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ProducerThread.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ProducerThread.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ProducerThread.java
new file mode 100644
index 0000000..9a4c1a7
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/messages/ProducerThread.java
@@ -0,0 +1,344 @@
+/*
+ * 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 org.apache.activemq.artemis.cli.commands.messages;
+
+import javax.jms.BytesMessage;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.utils.ReusableLatch;
+
+public class ProducerThread extends Thread {
+
+ protected final Session session;
+
+ boolean verbose;
+ int messageCount = 1000;
+ boolean runIndefinitely = false;
+ Destination destination;
+ int sleep = 0;
+ boolean persistent = true;
+ int messageSize = 0;
+ int textMessageSize;
+ long msgTTL = 0L;
+ String msgGroupID = null;
+ int transactionBatchSize;
+
+ int transactions = 0;
+ final AtomicInteger sentCount = new AtomicInteger(0);
+ String message;
+ String messageText = null;
+ String payloadUrl = null;
+ byte[] payload = null;
+ boolean running = false;
+ final ReusableLatch finished = new ReusableLatch(1);
+ final ReusableLatch paused = new ReusableLatch(0);
+
+ public ProducerThread(Session session, Destination destination, int threadNr) {
+ super("Producer " + destination.toString() + ", thread=" + threadNr);
+ this.destination = destination;
+ this.session = session;
+ }
+
+ @Override
+ public void run() {
+ MessageProducer producer = null;
+ String threadName = Thread.currentThread().getName();
+ try {
+ producer = session.createProducer(destination);
+ producer.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+ producer.setTimeToLive(msgTTL);
+ initPayLoad();
+ running = true;
+
+ System.out.println(threadName + " Started to calculate elapsed time ...\n");
+ long tStart = System.currentTimeMillis();
+
+ if (runIndefinitely) {
+ while (running) {
+ paused.await();
+ sendMessage(producer, threadName);
+ sentCount.incrementAndGet();
+ }
+ } else {
+ for (sentCount.set(0); sentCount.get() < messageCount && running; sentCount.incrementAndGet()) {
+ paused.await();
+ sendMessage(producer, threadName);
+ }
+ }
+
+ try {
+ session.commit();
+ } catch (Throwable ignored) {
+ }
+
+ System.out.println(threadName + " Produced: " + this.getSentCount() + " messages");
+ long tEnd = System.currentTimeMillis();
+ long elapsed = (tEnd - tStart) / 1000;
+ System.out.println(threadName + " Elapsed time in second : " + elapsed + " s");
+ System.out.println(threadName + " Elapsed time in milli second : " + (tEnd - tStart) + " milli seconds");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (finished != null) {
+ finished.countDown();
+ }
+ if (producer != null) {
+ try {
+ producer.close();
+ } catch (JMSException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void sendMessage(MessageProducer producer, String threadName) throws Exception {
+ Message message = createMessage(sentCount.get(), threadName);
+ producer.send(message);
+ if (verbose) {
+ System.out.println(threadName + " Sent: " + (message instanceof TextMessage ? ((TextMessage) message).getText() : message.getJMSMessageID()));
+ }
+
+ if (transactionBatchSize > 0 && sentCount.get() > 0 && sentCount.get() % transactionBatchSize == 0) {
+ System.out.println(threadName + " Committing transaction: " + transactions++);
+ session.commit();
+ }
+
+ if (sleep > 0) {
+ Thread.sleep(sleep);
+ }
+ }
+
+ private void initPayLoad() {
+ if (messageSize > 0) {
+ payload = new byte[messageSize];
+ for (int i = 0; i < payload.length; i++) {
+ payload[i] = '.';
+ }
+ }
+ }
+
+ protected Message createMessage(int i, String threadName) throws Exception {
+ Message answer;
+ if (payload != null) {
+ answer = session.createBytesMessage();
+ ((BytesMessage) answer).writeBytes(payload);
+ } else {
+ if (textMessageSize > 0) {
+ if (messageText == null) {
+ messageText = readInputStream(getClass().getResourceAsStream("demo.txt"), textMessageSize, i);
+ }
+ } else if (payloadUrl != null) {
+ messageText = readInputStream(new URL(payloadUrl).openStream(), -1, i);
+ } else if (message != null) {
+ messageText = message;
+ } else {
+ messageText = createDefaultMessage(i);
+ }
+ answer = session.createTextMessage(messageText);
+ }
+ if ((msgGroupID != null) && (!msgGroupID.isEmpty())) {
+ answer.setStringProperty("JMSXGroupID", msgGroupID);
+ }
+
+ answer.setIntProperty("count", i);
+ answer.setStringProperty("ThreadSent", threadName);
+ return answer;
+ }
+
+ private String readInputStream(InputStream is, int size, int messageNumber) throws IOException {
+ try (InputStreamReader reader = new InputStreamReader(is)) {
+ char[] buffer;
+ if (size > 0) {
+ buffer = new char[size];
+ } else {
+ buffer = new char[1024];
+ }
+ int count;
+ StringBuilder builder = new StringBuilder();
+ while ((count = reader.read(buffer)) != -1) {
+ builder.append(buffer, 0, count);
+ if (size > 0)
+ break;
+ }
+ return builder.toString();
+ } catch (IOException ioe) {
+ return createDefaultMessage(messageNumber);
+ }
+ }
+
+ private String createDefaultMessage(int messageNumber) {
+ return "test message: " + messageNumber;
+ }
+
+ public ProducerThread setMessageCount(int messageCount) {
+ this.messageCount = messageCount;
+ return this;
+ }
+
+ public int getSleep() {
+ return sleep;
+ }
+
+ public ProducerThread setSleep(int sleep) {
+ this.sleep = sleep;
+ return this;
+ }
+
+ public int getMessageCount() {
+ return messageCount;
+ }
+
+ public int getSentCount() {
+ return sentCount.get();
+ }
+
+ public boolean isPersistent() {
+ return persistent;
+ }
+
+ public ProducerThread setPersistent(boolean persistent) {
+ this.persistent = persistent;
+ return this;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ public ProducerThread setRunning(boolean running) {
+ this.running = running;
+ return this;
+ }
+
+ public long getMsgTTL() {
+ return msgTTL;
+ }
+
+ public ProducerThread setMsgTTL(long msgTTL) {
+ this.msgTTL = msgTTL;
+ return this;
+ }
+
+ public int getTransactionBatchSize() {
+ return transactionBatchSize;
+ }
+
+ public ProducerThread setTransactionBatchSize(int transactionBatchSize) {
+ this.transactionBatchSize = transactionBatchSize;
+ return this;
+ }
+
+ public String getMsgGroupID() {
+ return msgGroupID;
+ }
+
+ public ProducerThread setMsgGroupID(String msgGroupID) {
+ this.msgGroupID = msgGroupID;
+ return this;
+ }
+
+ public int getTextMessageSize() {
+ return textMessageSize;
+ }
+
+ public ProducerThread setTextMessageSize(int textMessageSize) {
+ this.textMessageSize = textMessageSize;
+ return this;
+ }
+
+ public int getMessageSize() {
+ return messageSize;
+ }
+
+ public ProducerThread setMessageSize(int messageSize) {
+ this.messageSize = messageSize;
+ return this;
+ }
+
+ public ReusableLatch getFinished() {
+ return finished;
+ }
+
+ public ProducerThread setFinished(int value) {
+ finished.setCount(value);
+ return this;
+ }
+
+ public String getPayloadUrl() {
+ return payloadUrl;
+ }
+
+ public ProducerThread setPayloadUrl(String payloadUrl) {
+ this.payloadUrl = payloadUrl;
+ return this;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public ProducerThread setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public boolean isRunIndefinitely() {
+ return runIndefinitely;
+ }
+
+ public ProducerThread setRunIndefinitely(boolean runIndefinitely) {
+ this.runIndefinitely = runIndefinitely;
+ return this;
+ }
+
+ public ProducerThread pauseProducer() {
+ this.paused.countUp();
+ return this;
+ }
+
+ public ProducerThread resumeProducer() {
+ this.paused.countDown();
+ return this;
+ }
+
+ public ProducerThread resetCounters() {
+ this.sentCount.set(0);
+ return this;
+ }
+
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ public ProducerThread setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/HelpQueue.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/HelpQueue.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/HelpQueue.java
index f106a18..dc2bd45 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/HelpQueue.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/HelpQueue.java
@@ -25,7 +25,7 @@ import io.airlift.airline.Help;
import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
-import org.apache.activemq.artemis.util.OptionsUtil;
+import org.apache.activemq.artemis.cli.commands.OptionsUtil;
public class HelpQueue extends Help implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
deleted file mode 100644
index 2959828..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/CompactJournal.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import java.io.File;
-
-import io.airlift.airline.Command;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
-import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-
-@Command(name = "compact", description = "Compacts the journal of a non running server")
-public final class CompactJournal extends LockAbstract {
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- super.execute(context);
- try {
- Configuration configuration = getFileConfiguration();
- compactJournal(new File(getJournal()), "activemq-data", "amq", configuration.getJournalMinFiles(), configuration.getJournalFileSize(), null);
- System.out.println("Compactation succeeded for " + getJournal());
- compactJournal(new File(getBinding()), "activemq-bindings", "bindings", 2, 1048576, null);
- System.out.println("Compactation succeeded for " + getBinding());
-
- } catch (Exception e) {
- treatError(e, "data", "compact");
- }
- return null;
- }
-
- void compactJournal(final File directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final IOCriticalErrorListener listener) throws Exception {
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(directory, listener, 1);
-
- JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
-
- journal.start();
-
- journal.loadInternalOnly();
-
- journal.compact();
-
- journal.stop();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
deleted file mode 100644
index f290eba..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/DecodeJournal.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import io.airlift.airline.Command;
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.utils.Base64;
-
-@Command(name = "decode", description = "Decode a journal's internal format into a new journal set of files")
-public class DecodeJournal extends LockAbstract {
-
- @Option(name = "--directory", description = "The journal folder (default journal folder from broker.xml)")
- public String directory;
-
- @Option(name = "--prefix", description = "The journal prefix (default activemq-data)")
- public String prefix = "activemq-data";
-
- @Option(name = "--suffix", description = "The journal suffix (default amq)")
- public String suffix = "amq";
-
- @Option(name = "--file-size", description = "The journal size (default 10485760)")
- public int size = 10485760;
-
- @Option(name = "--input", description = "The input file name (default=exp.dmp)", required = true)
- public String input = "exp.dmp";
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- super.execute(context);
- try {
- if (directory == null) {
- directory = getFileConfiguration().getJournalDirectory();
- }
- importJournal(directory, prefix, suffix, 2, size, input);
- } catch (Exception e) {
- treatError(e, "data", "decode");
- }
-
- return null;
- }
-
- public static void importJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final String fileInput) throws Exception {
- FileInputStream fileInputStream = new FileInputStream(new File(fileInput));
- importJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, fileInputStream);
-
- }
-
- public static void importJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final InputStream stream) throws Exception {
- Reader reader = new InputStreamReader(stream);
- importJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, reader);
- }
-
- public static void importJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final Reader reader) throws Exception {
-
- File journalDir = new File(directory);
-
- if (!journalDir.exists()) {
- if (!journalDir.mkdirs())
- System.err.println("Could not create directory " + directory);
- }
-
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
-
- JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
-
- if (journal.orderFiles().size() != 0) {
- throw new IllegalStateException("Import needs to create a brand new journal");
- }
-
- journal.start();
-
- // The journal is empty, as we checked already. Calling load just to initialize the internal data
- journal.loadInternalOnly();
-
- BufferedReader buffReader = new BufferedReader(reader);
-
- String line;
-
- HashMap<Long, AtomicInteger> txCounters = new HashMap<>();
-
- long lineNumber = 0;
-
- while ((line = buffReader.readLine()) != null) {
- lineNumber++;
- String[] splitLine = line.split(",");
- if (splitLine[0].equals("#File")) {
- txCounters.clear();
- continue;
- }
-
- Properties lineProperties = parseLine(splitLine);
-
- String operation = null;
- try {
- operation = lineProperties.getProperty("operation");
-
- if (operation.equals("AddRecord")) {
- RecordInfo info = parseRecord(lineProperties);
- journal.appendAddRecord(info.id, info.userRecordType, info.data, false);
- } else if (operation.equals("AddRecordTX")) {
- long txID = parseLong("txID", lineProperties);
- AtomicInteger counter = getCounter(txID, txCounters);
- counter.incrementAndGet();
- RecordInfo info = parseRecord(lineProperties);
- journal.appendAddRecordTransactional(txID, info.id, info.userRecordType, info.data);
- } else if (operation.equals("UpdateTX")) {
- long txID = parseLong("txID", lineProperties);
- AtomicInteger counter = getCounter(txID, txCounters);
- counter.incrementAndGet();
- RecordInfo info = parseRecord(lineProperties);
- journal.appendUpdateRecordTransactional(txID, info.id, info.userRecordType, info.data);
- } else if (operation.equals("Update")) {
- RecordInfo info = parseRecord(lineProperties);
- journal.appendUpdateRecord(info.id, info.userRecordType, info.data, false);
- } else if (operation.equals("DeleteRecord")) {
- long id = parseLong("id", lineProperties);
-
- try {
- journal.appendDeleteRecord(id, false);
- } catch (IllegalStateException ignored) {
- // If not found it means the append/update records were reclaimed already
- }
- } else if (operation.equals("DeleteRecordTX")) {
- long txID = parseLong("txID", lineProperties);
- long id = parseLong("id", lineProperties);
- AtomicInteger counter = getCounter(txID, txCounters);
- counter.incrementAndGet();
- journal.appendDeleteRecordTransactional(txID, id);
- } else if (operation.equals("Prepare")) {
- long txID = parseLong("txID", lineProperties);
- int numberOfRecords = parseInt("numberOfRecords", lineProperties);
- AtomicInteger counter = getCounter(txID, txCounters);
- byte[] data = parseEncoding("extraData", lineProperties);
-
- if (counter.get() == numberOfRecords) {
- journal.appendPrepareRecord(txID, data, false);
- } else {
- System.err.println("Transaction " + txID +
- " at line " +
- lineNumber +
- " is incomplete. The prepare record expected " +
- numberOfRecords +
- " while the import only had " +
- counter);
- }
- } else if (operation.equals("Commit")) {
- long txID = parseLong("txID", lineProperties);
- int numberOfRecords = parseInt("numberOfRecords", lineProperties);
- AtomicInteger counter = getCounter(txID, txCounters);
- if (counter.get() == numberOfRecords) {
- journal.appendCommitRecord(txID, false);
- } else {
- System.err.println("Transaction " + txID +
- " at line " +
- lineNumber +
- " is incomplete. The commit record expected " +
- numberOfRecords +
- " while the import only had " +
- counter);
- }
- } else if (operation.equals("Rollback")) {
- long txID = parseLong("txID", lineProperties);
- journal.appendRollbackRecord(txID, false);
- } else {
- System.err.println("Invalid operation " + operation + " at line " + lineNumber);
- }
- } catch (Exception ex) {
- System.err.println("Error at line " + lineNumber + ", operation=" + operation + " msg = " + ex.getMessage());
- }
- }
-
- journal.stop();
- }
-
- protected static AtomicInteger getCounter(final Long txID, final Map<Long, AtomicInteger> txCounters) {
-
- AtomicInteger counter = txCounters.get(txID);
- if (counter == null) {
- counter = new AtomicInteger(0);
- txCounters.put(txID, counter);
- }
-
- return counter;
- }
-
- protected static RecordInfo parseRecord(final Properties properties) throws Exception {
- long id = parseLong("id", properties);
- byte userRecordType = parseByte("userRecordType", properties);
- boolean isUpdate = parseBoolean("isUpdate", properties);
- byte[] data = parseEncoding("data", properties);
- return new RecordInfo(id, userRecordType, data, isUpdate, (short) 0);
- }
-
- private static byte[] parseEncoding(final String name, final Properties properties) throws Exception {
- String value = parseString(name, properties);
-
- return decode(value);
- }
-
- /**
- * @param properties
- * @return
- */
- private static int parseInt(final String name, final Properties properties) throws Exception {
- String value = parseString(name, properties);
-
- return Integer.parseInt(value);
- }
-
- private static long parseLong(final String name, final Properties properties) throws Exception {
- String value = parseString(name, properties);
-
- return Long.parseLong(value);
- }
-
- private static boolean parseBoolean(final String name, final Properties properties) throws Exception {
- String value = parseString(name, properties);
-
- return Boolean.parseBoolean(value);
- }
-
- private static byte parseByte(final String name, final Properties properties) throws Exception {
- String value = parseString(name, properties);
-
- return Byte.parseByte(value);
- }
-
- /**
- * @param name
- * @param properties
- * @return
- * @throws Exception
- */
- private static String parseString(final String name, final Properties properties) throws Exception {
- String value = properties.getProperty(name);
-
- if (value == null) {
- throw new Exception("property " + name + " not found");
- }
- return value;
- }
-
- protected static Properties parseLine(final String[] splitLine) {
- Properties properties = new Properties();
-
- for (String el : splitLine) {
- String[] tuple = el.split("@");
- if (tuple.length == 2) {
- properties.put(tuple[0], tuple[1]);
- } else {
- properties.put(tuple[0], tuple[0]);
- }
- }
-
- return properties;
- }
-
- private static byte[] decode(final String data) {
- return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
- public void printUsage() {
- for (int i = 0; i < 10; i++) {
- System.err.println();
- }
- System.err.println("This method will export the journal at low level record.");
- System.err.println();
- System.err.println();
- for (int i = 0; i < 10; i++) {
- System.err.println();
- }
- }
-
-}
[4/6] activemq-artemis git commit: ARTEMIS-904 Remove cyclic
dependencies from artemis-cli
Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
deleted file mode 100644
index e5fd80c..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/EncodeJournal.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.util.List;
-
-import io.airlift.airline.Command;
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.core.io.SequentialFileFactory;
-import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.impl.JournalFile;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.journal.impl.JournalReaderCallback;
-import org.apache.activemq.artemis.utils.Base64;
-
-@Command(name = "encode", description = "Encode a set of journal files into an internal encoded data format")
-public class EncodeJournal extends LockAbstract {
-
- @Option(name = "--directory", description = "The journal folder (default the journal folder from broker.xml)")
- public String directory;
-
- @Option(name = "--prefix", description = "The journal prefix (default activemq-data)")
- public String prefix = "activemq-data";
-
- @Option(name = "--suffix", description = "The journal suffix (default amq)")
- public String suffix = "amq";
-
- @Option(name = "--file-size", description = "The journal size (default 10485760)")
- public int size = 10485760;
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- super.execute(context);
- try {
- if (directory == null) {
- directory = getFileConfiguration().getJournalDirectory();
- }
-
- exportJournal(directory, prefix, suffix, 2, size);
- } catch (Exception e) {
- treatError(e, "data", "encode");
- }
-
- return null;
- }
-
- public static void exportJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize) throws Exception {
-
- exportJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, System.out);
- }
-
- public static void exportJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final String fileName) throws Exception {
- try (FileOutputStream fileOutputStream = new FileOutputStream(fileName);
- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
- PrintStream out = new PrintStream(bufferedOutputStream)) {
- exportJournal(directory, journalPrefix, journalSuffix, minFiles, fileSize, out);
- }
- }
-
- public static void exportJournal(final String directory,
- final String journalPrefix,
- final String journalSuffix,
- final int minFiles,
- final int fileSize,
- final PrintStream out) throws Exception {
- NIOSequentialFileFactory nio = new NIOSequentialFileFactory(new File(directory), null, 1);
-
- JournalImpl journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, nio, journalPrefix, journalSuffix, 1);
-
- List<JournalFile> files = journal.orderFiles();
-
- for (JournalFile file : files) {
- out.println("#File," + file);
-
- exportJournalFile(out, nio, file);
- }
- }
-
- /**
- * @param out
- * @param fileFactory
- * @param file
- * @throws Exception
- */
- public static void exportJournalFile(final PrintStream out,
- final SequentialFileFactory fileFactory,
- final JournalFile file) throws Exception {
- JournalImpl.readJournalFile(fileFactory, file, new JournalReaderCallback() {
-
- @Override
- public void onReadUpdateRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
- out.println("operation@UpdateTX,txID@" + transactionID + "," + describeRecord(recordInfo));
- }
-
- @Override
- public void onReadUpdateRecord(final RecordInfo recordInfo) throws Exception {
- out.println("operation@Update," + describeRecord(recordInfo));
- }
-
- @Override
- public void onReadRollbackRecord(final long transactionID) throws Exception {
- out.println("operation@Rollback,txID@" + transactionID);
- }
-
- @Override
- public void onReadPrepareRecord(final long transactionID,
- final byte[] extraData,
- final int numberOfRecords) throws Exception {
- out.println("operation@Prepare,txID@" + transactionID +
- ",numberOfRecords@" +
- numberOfRecords +
- ",extraData@" +
- encode(extraData));
- }
-
- @Override
- public void onReadDeleteRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
- out.println("operation@DeleteRecordTX,txID@" + transactionID +
- "," +
- describeRecord(recordInfo));
- }
-
- @Override
- public void onReadDeleteRecord(final long recordID) throws Exception {
- out.println("operation@DeleteRecord,id@" + recordID);
- }
-
- @Override
- public void onReadCommitRecord(final long transactionID, final int numberOfRecords) throws Exception {
- out.println("operation@Commit,txID@" + transactionID + ",numberOfRecords@" + numberOfRecords);
- }
-
- @Override
- public void onReadAddRecordTX(final long transactionID, final RecordInfo recordInfo) throws Exception {
- out.println("operation@AddRecordTX,txID@" + transactionID + "," + describeRecord(recordInfo));
- }
-
- @Override
- public void onReadAddRecord(final RecordInfo recordInfo) throws Exception {
- out.println("operation@AddRecord," + describeRecord(recordInfo));
- }
-
- @Override
- public void markAsDataFile(final JournalFile file) {
- }
- });
- }
-
- private static String describeRecord(final RecordInfo recordInfo) {
- return "id@" + recordInfo.id +
- ",userRecordType@" +
- recordInfo.userRecordType +
- ",length@" +
- recordInfo.data.length +
- ",isUpdate@" +
- recordInfo.isUpdate +
- ",compactCount@" +
- recordInfo.compactCount +
- ",data@" +
- encode(recordInfo.data);
- }
-
- private static String encode(final byte[] data) {
- return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
- public void printUsage() {
- for (int i = 0; i < 10; i++) {
- System.err.println();
- }
- System.err.println("This method will export the journal at low level record.");
- System.err.println();
- System.err.println();
- for (int i = 0; i < 10; i++) {
- System.err.println();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/HelpData.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/HelpData.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/HelpData.java
index a7a27a6..86b9a60 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/HelpData.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/HelpData.java
@@ -25,7 +25,7 @@ import io.airlift.airline.Help;
import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
-import org.apache.activemq.artemis.util.OptionsUtil;
+import org.apache.activemq.artemis.cli.commands.OptionsUtil;
public class HelpData extends Help implements Action {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/LockAbstract.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/LockAbstract.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/LockAbstract.java
index 5bffb36..cbc5234 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/LockAbstract.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/LockAbstract.java
@@ -32,15 +32,6 @@ public abstract class LockAbstract extends DataAbstract {
private static RandomAccessFile serverLockFile = null;
private static FileLock serverLockLock = null;
- protected File getLockPlace() throws Exception {
- String brokerInstance = getBrokerInstance();
- if (brokerInstance != null) {
- return new File(new File(brokerInstance), "lock");
- } else {
- return null;
- }
- }
-
public static void unlock() {
try {
if (serverLockFile != null) {
@@ -70,7 +61,7 @@ public abstract class LockAbstract extends DataAbstract {
return null;
}
- protected void lockCLI(File lockPlace) throws Exception {
+ void lockCLI(File lockPlace) throws Exception {
if (lockPlace != null) {
lockPlace.mkdirs();
if (serverLockFile == null) {
@@ -89,4 +80,12 @@ public abstract class LockAbstract extends DataAbstract {
}
}
+ private File getLockPlace() throws Exception {
+ String brokerInstance = getBrokerInstance();
+ if (brokerInstance != null) {
+ return new File(new File(brokerInstance), "lock");
+ } else {
+ return null;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PerfJournal.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PerfJournal.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PerfJournal.java
deleted file mode 100644
index f7d89ec..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PerfJournal.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import java.text.DecimalFormat;
-
-import io.airlift.airline.Command;
-import io.airlift.airline.Option;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
-import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
-import org.apache.activemq.artemis.core.server.JournalType;
-
-@Command(name = "perf-journal", description = "Calculates the journal-buffer-timeout you should use with the current data folder")
-public class PerfJournal extends LockAbstract {
-
-
- @Option(name = "--block-size", description = "The block size for each write (default 4096)")
- public int size = 4 * 1024;
-
-
- @Option(name = "--writes", description = "The number of writes to be performed (default 250)")
- public int writes = 250;
-
- @Option(name = "--tries", description = "The number of tries for the test (default 5)")
- public int tries = 5;
-
- @Option(name = "--no-sync", description = "Disable sync")
- public boolean nosyncs = false;
-
- @Option(name = "--sync", description = "Enable syncs")
- public boolean syncs = false;
-
- @Option(name = "--journal-type", description = "Journal Type to be used (default from broker.xml)")
- public String journalType = null;
-
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- super.execute(context);
-
- FileConfiguration fileConfiguration = getFileConfiguration();
-
- if (nosyncs) {
- fileConfiguration.setJournalDatasync(false);
- } else if (syncs) {
- fileConfiguration.setJournalDatasync(true);
- }
-
-
- if (journalType != null) {
- fileConfiguration.setJournalType(JournalType.getType(journalType));
- }
-
- System.out.println("");
- System.out.println("Auto tuning journal ...");
-
- System.out.println("Performing " + tries + " tests writing " + writes + " blocks of " + size + " on each test, sync=" + fileConfiguration.isJournalDatasync() + " with journalType = " + fileConfiguration.getJournalType());
-
- fileConfiguration.getJournalLocation().mkdirs();
-
- long time = SyncCalculation.syncTest(fileConfiguration.getJournalLocation(), size, writes, tries, verbose, fileConfiguration.isJournalDatasync(), fileConfiguration.getJournalType());
-
- long nanosecondsWait = SyncCalculation.toNanos(time, writes, verbose);
- double writesPerMillisecond = (double) writes / (double) time;
-
- String writesPerMillisecondStr = new DecimalFormat("###.##").format(writesPerMillisecond);
-
- context.out.println("Your system can execute " + writesPerMillisecondStr + " syncs per millisecond");
- context.out.println("Your journal-buffer-timeout should be:" + nanosecondsWait);
- context.out.println("You should use this following configuration:");
- context.out.println();
- context.out.println("<journal-buffer-timeout>" + nanosecondsWait + "</journal-buffer-timeout>");
-
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PrintData.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PrintData.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PrintData.java
index 2816aaf..d5e895d 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PrintData.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/PrintData.java
@@ -17,6 +17,8 @@
package org.apache.activemq.artemis.cli.commands.tools;
import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -31,7 +33,6 @@ import io.airlift.airline.Command;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.cli.Artemis;
import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.core.journal.RecordInfo;
import org.apache.activemq.artemis.core.message.impl.CoreMessagePersister;
@@ -81,7 +82,7 @@ public class PrintData extends OptionalLocking {
public static void printData(File bindingsDirectory, File messagesDirectory, File pagingDirectory) throws Exception {
// Having the version on the data report is an information very useful to understand what happened
// When debugging stuff
- Artemis.printBanner();
+ printBanner();
File serverLockFile = new File(messagesDirectory, "server.lock");
@@ -135,6 +136,20 @@ public class PrintData extends OptionalLocking {
}
+ public static void printBanner() throws Exception {
+ copy(PrintData.class.getResourceAsStream("banner.txt"), System.out);
+ }
+
+ private static long copy(InputStream in, OutputStream out) throws Exception {
+ byte[] buffer = new byte[1024];
+ int len = in.read(buffer);
+ while (len != -1) {
+ out.write(buffer, 0, len);
+ len = in.read(buffer);
+ }
+ return len;
+ }
+
private static void printPages(File pageDirectory, DescribeJournal describeJournal) {
try {
@@ -214,12 +229,9 @@ public class PrintData extends OptionalLocking {
System.out.println();
msgID++;
}
-
pgid++;
-
}
}
-
} catch (Exception e) {
e.printStackTrace();
}
@@ -228,7 +240,7 @@ public class PrintData extends OptionalLocking {
/**
* Calculate the acks on the page system
*/
- protected static PageCursorsInfo calculateCursorsInfo(List<RecordInfo> records) throws Exception {
+ private static PageCursorsInfo calculateCursorsInfo(List<RecordInfo> records) throws Exception {
PageCursorsInfo cursorInfo = new PageCursorsInfo();
@@ -293,25 +305,18 @@ public class PrintData extends OptionalLocking {
/**
* @return the pgTXs
*/
- public Set<Long> getPgTXs() {
+ Set<Long> getPgTXs() {
return pgTXs;
}
/**
* @return the cursorRecords
*/
- public Map<Long, Set<PagePosition>> getCursorRecords() {
+ Map<Long, Set<PagePosition>> getCursorRecords() {
return cursorRecords;
}
- /**
- * @return the completePages
- */
- public Map<Long, Set<Long>> getCompletePages() {
- return completePages;
- }
-
- public Set<Long> getCompletePages(Long queueID) {
+ Set<Long> getCompletePages(Long queueID) {
Set<Long> completePagesSet = completePages.get(queueID);
if (completePagesSet == null) {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java
deleted file mode 100644
index be7e84e..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-/**
- * The constants shared by <code>org.apache.activemq.tools.XmlDataImporter</code> and
- * <code>org.apache.activemq.tools.XmlDataExporter</code>.
- */
-public final class XmlDataConstants {
-
- private XmlDataConstants() {
- // Utility
- }
-
- public static final String XML_VERSION = "1.0";
- public static final String DOCUMENT_PARENT = "activemq-journal";
- public static final String BINDINGS_PARENT = "bindings";
-
- public static final String QUEUE_BINDINGS_CHILD = "queue-binding";
- public static final String QUEUE_BINDING_ADDRESS = "address";
- public static final String QUEUE_BINDING_FILTER_STRING = "filter-string";
- public static final String QUEUE_BINDING_NAME = "name";
- public static final String QUEUE_BINDING_ID = "id";
- public static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type";
-
- public static final String ADDRESS_BINDINGS_CHILD = "address-binding";
- public static final String ADDRESS_BINDING_NAME = "name";
- public static final String ADDRESS_BINDING_ID = "id";
- public static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types";
-
- public static final String MESSAGES_PARENT = "messages";
- public static final String MESSAGES_CHILD = "message";
- public static final String MESSAGE_ID = "id";
- public static final String MESSAGE_PRIORITY = "priority";
- public static final String MESSAGE_EXPIRATION = "expiration";
- public static final String MESSAGE_TIMESTAMP = "timestamp";
- public static final String DEFAULT_TYPE_PRETTY = "default";
- public static final String BYTES_TYPE_PRETTY = "bytes";
- public static final String MAP_TYPE_PRETTY = "map";
- public static final String OBJECT_TYPE_PRETTY = "object";
- public static final String STREAM_TYPE_PRETTY = "stream";
- public static final String TEXT_TYPE_PRETTY = "text";
- public static final String MESSAGE_TYPE = "type";
- public static final String MESSAGE_IS_LARGE = "isLarge";
- public static final String MESSAGE_USER_ID = "user-id";
- public static final String MESSAGE_BODY = "body";
- public static final String PROPERTIES_PARENT = "properties";
- public static final String PROPERTIES_CHILD = "property";
- public static final String PROPERTY_NAME = "name";
- public static final String PROPERTY_VALUE = "value";
- public static final String PROPERTY_TYPE = "type";
- public static final String QUEUES_PARENT = "queues";
- public static final String QUEUES_CHILD = "queue";
- public static final String QUEUE_NAME = "name";
- public static final String PROPERTY_TYPE_BOOLEAN = "boolean";
- public static final String PROPERTY_TYPE_BYTE = "byte";
- public static final String PROPERTY_TYPE_BYTES = "bytes";
- public static final String PROPERTY_TYPE_SHORT = "short";
- public static final String PROPERTY_TYPE_INTEGER = "integer";
- public static final String PROPERTY_TYPE_LONG = "long";
- public static final String PROPERTY_TYPE_FLOAT = "float";
- public static final String PROPERTY_TYPE_DOUBLE = "double";
- public static final String PROPERTY_TYPE_STRING = "string";
- public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
-
- static final String JMS_CONNECTION_FACTORY_NAME = "name";
- static final String JMS_CONNECTION_FACTORY_CLIENT_ID = "client-id";
- static final String JMS_CONNECTION_FACTORY_CALL_FAILOVER_TIMEOUT = "call-failover-timeout";
- static final String JMS_CONNECTION_FACTORY_CALL_TIMEOUT = "call-timeout";
- static final String JMS_CONNECTION_FACTORY_CLIENT_FAILURE_CHECK_PERIOD = "client-failure-check-period";
- static final String JMS_CONNECTION_FACTORY_CONFIRMATION_WINDOW_SIZE = "confirmation-window-size";
- static final String JMS_CONNECTION_FACTORY_CONNECTION_TTL = "connection-ttl";
- static final String JMS_CONNECTION_FACTORY_CONSUMER_MAX_RATE = "consumer-max-rate";
- static final String JMS_CONNECTION_FACTORY_CONSUMER_WINDOW_SIZE = "consumer-window-size";
- static final String JMS_CONNECTION_FACTORY_DISCOVERY_GROUP_NAME = "discovery-group-name";
- static final String JMS_CONNECTION_FACTORY_DUPS_OK_BATCH_SIZE = "dups-ok-batch-size";
- static final String JMS_CONNECTION_FACTORY_TYPE = "type";
- static final String JMS_CONNECTION_FACTORY_GROUP_ID = "group-id";
- static final String JMS_CONNECTION_FACTORY_LOAD_BALANCING_POLICY_CLASS_NAME = "load-balancing-policy-class-name";
- static final String JMS_CONNECTION_FACTORY_MAX_RETRY_INTERVAL = "max-retry-interval";
- static final String JMS_CONNECTION_FACTORY_MIN_LARGE_MESSAGE_SIZE = "min-large-message-size";
- static final String JMS_CONNECTION_FACTORY_PRODUCER_MAX_RATE = "producer-max-rate";
- static final String JMS_CONNECTION_FACTORY_PRODUCER_WINDOW_SIZE = "producer-window-size";
- static final String JMS_CONNECTION_FACTORY_RECONNECT_ATTEMPTS = "reconnect-attempts";
- static final String JMS_CONNECTION_FACTORY_RETRY_INTERVAL = "retry-interval";
- static final String JMS_CONNECTION_FACTORY_RETRY_INTERVAL_MULTIPLIER = "retry-interval-multiplier";
- static final String JMS_CONNECTION_FACTORY_SCHEDULED_THREAD_POOL_MAX_SIZE = "scheduled-thread-pool-max-size";
- static final String JMS_CONNECTION_FACTORY_THREAD_POOL_MAX_SIZE = "thread-pool-max-size";
- static final String JMS_CONNECTION_FACTORY_TRANSACTION_BATCH_SIZE = "transaction-batch-size";
- static final String JMS_CONNECTION_FACTORY_CONNECTORS = "connectors";
- static final String JMS_CONNECTION_FACTORY_CONNECTOR = "connector";
- static final String JMS_CONNECTION_FACTORY_AUTO_GROUP = "auto-group";
- static final String JMS_CONNECTION_FACTORY_BLOCK_ON_ACKNOWLEDGE = "block-on-acknowledge";
- static final String JMS_CONNECTION_FACTORY_BLOCK_ON_DURABLE_SEND = "block-on-durable-send";
- static final String JMS_CONNECTION_FACTORY_BLOCK_ON_NON_DURABLE_SEND = "block-on-non-durable-send";
- static final String JMS_CONNECTION_FACTORY_CACHE_LARGE_MESSAGES_CLIENT = "cache-large-messages-client";
- static final String JMS_CONNECTION_FACTORY_COMPRESS_LARGE_MESSAGES = "compress-large-messages";
- static final String JMS_CONNECTION_FACTORY_FAILOVER_ON_INITIAL_CONNECTION = "failover-on-initial-connection";
- static final String JMS_CONNECTION_FACTORY_HA = "ha";
- static final String JMS_CONNECTION_FACTORY_PREACKNOWLEDGE = "preacknowledge";
- static final String JMS_CONNECTION_FACTORY_USE_GLOBAL_POOLS = "use-global-pools";
-
- static final String JMS_DESTINATIONS = "jms-destinations";
- static final String JMS_DESTINATION = "jms-destination";
- static final String JMS_DESTINATION_NAME = "name";
- static final String JMS_DESTINATION_SELECTOR = "selector";
- static final String JMS_DESTINATION_TYPE = "type";
-
- static final String JMS_JNDI_ENTRIES = "entries";
- static final String JMS_JNDI_ENTRY = "entry";
-
- public static final String JNDI_COMPATIBILITY_PREFIX = "java:jboss/exported/";
-
- static final String NULL = "_AMQ_NULL";
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
deleted file mode 100644
index d2f6204..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.File;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-import io.airlift.airline.Command;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ICoreMessage;
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.RoutingType;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.cli.commands.ActionContext;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
-import org.apache.activemq.artemis.core.journal.Journal;
-import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.TransactionFailureCallback;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.message.LargeBodyEncoder;
-import org.apache.activemq.artemis.core.paging.PagedMessage;
-import org.apache.activemq.artemis.core.paging.PagingManager;
-import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
-import org.apache.activemq.artemis.core.paging.cursor.PagePosition;
-import org.apache.activemq.artemis.core.paging.cursor.impl.PagePositionImpl;
-import org.apache.activemq.artemis.core.paging.impl.Page;
-import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
-import org.apache.activemq.artemis.core.paging.impl.PagingManagerImpl;
-import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
-import org.apache.activemq.artemis.core.persistence.impl.journal.AckDescribe;
-import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
-import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.MessageDescribe;
-import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.ReferenceDescribe;
-import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
-import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
-import org.apache.activemq.artemis.core.persistence.impl.journal.codec.CursorAckRecordEncoding;
-import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageUpdateTXEncoding;
-import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentAddressBindingEncoding;
-import org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentQueueBindingEncoding;
-import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
-import org.apache.activemq.artemis.core.server.JournalType;
-import org.apache.activemq.artemis.core.server.LargeServerMessage;
-import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.activemq.artemis.utils.ExecutorFactory;
-import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
-
-@Command(name = "exp", description = "Export all message-data using an XML that could be interpreted by any system.")
-public final class XmlDataExporter extends OptionalLocking {
-
- private static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
-
- private JournalStorageManager storageManager;
-
- private Configuration config;
-
- private XMLStreamWriter xmlWriter;
-
- // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
- private final Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs = new HashMap<>();
-
- // map of all message records hashed by their record ID (which will match the record ID of the message refs)
- private final HashMap<Long, Message> messages = new HashMap<>();
-
- private final Map<Long, Set<PagePosition>> cursorRecords = new HashMap<>();
-
- private final Set<Long> pgTXs = new HashSet<>();
-
- private final HashMap<Long, PersistentQueueBindingEncoding> queueBindings = new HashMap<>();
-
- private final HashMap<Long, PersistentAddressBindingEncoding> addressBindings = new HashMap<>();
-
- long messagesPrinted = 0L;
-
- long bindingsPrinted = 0L;
-
- @Override
- public Object execute(ActionContext context) throws Exception {
- super.execute(context);
-
- try {
- process(context.out, getBinding(), getJournal(), getPaging(), getLargeMessages());
- } catch (Exception e) {
- treatError(e, "data", "exp");
- }
- return null;
- }
-
- public void process(OutputStream out,
- String bindingsDir,
- String journalDir,
- String pagingDir,
- String largeMessagesDir) throws Exception {
- config = new ConfigurationImpl().setBindingsDirectory(bindingsDir).setJournalDirectory(journalDir).setPagingDirectory(pagingDir).setLargeMessagesDirectory(largeMessagesDir).setJournalType(JournalType.NIO);
- final ExecutorService executor = Executors.newFixedThreadPool(5, ActiveMQThreadFactory.defaultThreadFactory());
- ExecutorFactory executorFactory = new OrderedExecutorFactory(executor);
-
- storageManager = new JournalStorageManager(config, executorFactory, executorFactory);
-
- XMLOutputFactory factory = XMLOutputFactory.newInstance();
- XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out, "UTF-8");
- PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
- xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(), new Class[]{XMLStreamWriter.class}, handler);
-
- writeXMLData();
-
- executor.shutdown();
- }
-
- private void writeXMLData() throws Exception {
- long start = System.currentTimeMillis();
- getBindings();
- processMessageJournal();
- printDataAsXML();
- ActiveMQServerLogger.LOGGER.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
- ActiveMQServerLogger.LOGGER.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
- }
-
- /**
- * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
- * use this data later to print all the right information.
- *
- * @throws Exception will be thrown if anything goes wrong reading the journal
- */
- private void processMessageJournal() throws Exception {
- ArrayList<RecordInfo> acks = new ArrayList<>();
-
- List<RecordInfo> records = new LinkedList<>();
-
- // We load these, but don't use them.
- List<PreparedTransactionInfo> preparedTransactions = new LinkedList<>();
-
- Journal messageJournal = storageManager.getMessageJournal();
-
- ActiveMQServerLogger.LOGGER.debug("Reading journal from " + config.getJournalDirectory());
-
- messageJournal.start();
-
- // Just logging these, no action necessary
- TransactionFailureCallback transactionFailureCallback = new TransactionFailureCallback() {
- @Override
- public void failedTransaction(long transactionID,
- List<RecordInfo> records1,
- List<RecordInfo> recordsToDelete) {
- StringBuilder message = new StringBuilder();
- message.append("Encountered failed journal transaction: ").append(transactionID);
- for (int i = 0; i < records1.size(); i++) {
- if (i == 0) {
- message.append("; Records: ");
- }
- message.append(records1.get(i));
- if (i != (records1.size() - 1)) {
- message.append(", ");
- }
- }
-
- for (int i = 0; i < recordsToDelete.size(); i++) {
- if (i == 0) {
- message.append("; RecordsToDelete: ");
- }
- message.append(recordsToDelete.get(i));
- if (i != (recordsToDelete.size() - 1)) {
- message.append(", ");
- }
- }
-
- ActiveMQServerLogger.LOGGER.debug(message.toString());
- }
- };
-
- ((JournalImpl) messageJournal).load(records, preparedTransactions, transactionFailureCallback, false);
-
- // Since we don't use these nullify the reference so that the garbage collector can clean them up
- preparedTransactions = null;
-
- for (RecordInfo info : records) {
- byte[] data = info.data;
-
- ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(data);
-
- Object o = DescribeJournal.newObjectEncoding(info, storageManager);
- if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE) {
- messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
- } else if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE_PROTOCOL) {
- messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
- } else if (info.getUserRecordType() == JournalRecordIds.ADD_LARGE_MESSAGE) {
- messages.put(info.id, ((MessageDescribe) o).getMsg());
- } else if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
- ReferenceDescribe ref = (ReferenceDescribe) o;
- HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
- if (map == null) {
- HashMap<Long, ReferenceDescribe> newMap = new HashMap<>();
- newMap.put(ref.refEncoding.queueID, ref);
- messageRefs.put(info.id, newMap);
- } else {
- map.put(ref.refEncoding.queueID, ref);
- }
- } else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
- acks.add(info);
- } else if (info.userRecordType == JournalRecordIds.ACKNOWLEDGE_CURSOR) {
- CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
- encoding.decode(buff);
-
- Set<PagePosition> set = cursorRecords.get(encoding.queueID);
-
- if (set == null) {
- set = new HashSet<>();
- cursorRecords.put(encoding.queueID, set);
- }
-
- set.add(encoding.position);
- } else if (info.userRecordType == JournalRecordIds.PAGE_TRANSACTION) {
- if (info.isUpdate) {
- PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
-
- pageUpdate.decode(buff);
- pgTXs.add(pageUpdate.pageTX);
- } else {
- PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
-
- pageTransactionInfo.decode(buff);
-
- pageTransactionInfo.setRecordID(info.id);
- pgTXs.add(pageTransactionInfo.getTransactionID());
- }
- }
- }
-
- messageJournal.stop();
-
- removeAcked(acks);
- }
-
- /**
- * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
- *
- * @param acks the list of ack records we got from the journal
- */
- private void removeAcked(ArrayList<RecordInfo> acks) {
- for (RecordInfo info : acks) {
- AckDescribe ack = (AckDescribe) DescribeJournal.newObjectEncoding(info, null);
- HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
- referenceDescribeHashMap.remove(ack.refEncoding.queueID);
- if (referenceDescribeHashMap.size() == 0) {
- messages.remove(info.id);
- messageRefs.remove(info.id);
- }
- }
- }
-
- /**
- * Open the bindings journal and extract all bindings data.
- *
- * @throws Exception will be thrown if anything goes wrong reading the bindings journal
- */
- private void getBindings() throws Exception {
- List<RecordInfo> records = new LinkedList<>();
-
- Journal bindingsJournal = storageManager.getBindingsJournal();
-
- bindingsJournal.start();
-
- ActiveMQServerLogger.LOGGER.debug("Reading bindings journal from " + config.getBindingsDirectory());
-
- ((JournalImpl) bindingsJournal).load(records, null, null, false);
-
- for (RecordInfo info : records) {
- if (info.getUserRecordType() == JournalRecordIds.QUEUE_BINDING_RECORD) {
- PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) DescribeJournal.newObjectEncoding(info, null);
- queueBindings.put(bindingEncoding.getId(), bindingEncoding);
- } else if (info.getUserRecordType() == JournalRecordIds.ADDRESS_BINDING_RECORD) {
- PersistentAddressBindingEncoding bindingEncoding = (PersistentAddressBindingEncoding) DescribeJournal.newObjectEncoding(info, null);
- addressBindings.put(bindingEncoding.getId(), bindingEncoding);
- }
- }
-
- bindingsJournal.stop();
- }
-
- private void printDataAsXML() {
- try {
- xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
- xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
- printBindingsAsXML();
- printAllMessagesAsXML();
- xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
- xmlWriter.writeEndDocument();
- xmlWriter.flush();
- xmlWriter.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private void printBindingsAsXML() throws XMLStreamException {
- xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
- for (Map.Entry<Long, PersistentAddressBindingEncoding> addressBindingEncodingEntry : addressBindings.entrySet()) {
- PersistentAddressBindingEncoding bindingEncoding = addressBindings.get(addressBindingEncodingEntry.getKey());
- xmlWriter.writeEmptyElement(XmlDataConstants.ADDRESS_BINDINGS_CHILD);
- StringBuilder routingTypes = new StringBuilder();
- for (RoutingType routingType : bindingEncoding.getRoutingTypes()) {
- routingTypes.append(routingType.toString()).append(", ");
- }
- xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_ROUTING_TYPE, routingTypes.toString().substring(0, routingTypes.length() - 2));
- xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_NAME, bindingEncoding.getName().toString());
- xmlWriter.writeAttribute(XmlDataConstants.ADDRESS_BINDING_ID, Long.toString(bindingEncoding.getId()));
- bindingsPrinted++;
- }
- for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet()) {
- PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
- xmlWriter.writeEmptyElement(XmlDataConstants.QUEUE_BINDINGS_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ADDRESS, bindingEncoding.getAddress().toString());
- String filter = "";
- if (bindingEncoding.getFilterString() != null) {
- filter = bindingEncoding.getFilterString().toString();
- }
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_FILTER_STRING, filter);
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_NAME, bindingEncoding.getQueueName().toString());
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ID, Long.toString(bindingEncoding.getId()));
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_BINDING_ROUTING_TYPE, RoutingType.getType(bindingEncoding.getRoutingType()).toString());
- bindingsPrinted++;
- }
- xmlWriter.writeEndElement(); // end BINDINGS_PARENT
- }
-
- private void printAllMessagesAsXML() throws Exception {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
-
- // Order here is important. We must process the messages from the journal before we process those from the page
- // files in order to get the messages in the right order.
- for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet()) {
- printSingleMessageAsXML(messageMapEntry.getValue().toCore(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
- }
-
- printPagedMessagesAsXML();
-
- xmlWriter.writeEndElement(); // end "messages"
- }
-
- /**
- * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
- * from the journal).
- */
- private void printPagedMessagesAsXML() {
- try {
- ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1, ActiveMQThreadFactory.defaultThreadFactory());
- final ExecutorService executor = Executors.newFixedThreadPool(10, ActiveMQThreadFactory.defaultThreadFactory());
- ExecutorFactory executorFactory = new ExecutorFactory() {
- @Override
- public Executor getExecutor() {
- return executor;
- }
- };
- PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(storageManager, config.getPagingLocation(), 1000L, scheduled, executorFactory, true, null);
- HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<>();
- addressSettingsRepository.setDefault(new AddressSettings());
- PagingManager manager = new PagingManagerImpl(pageStoreFactory, addressSettingsRepository);
-
- manager.start();
-
- SimpleString[] stores = manager.getStoreNames();
-
- for (SimpleString store : stores) {
- PagingStore pageStore = manager.getPageStore(store);
-
- if (pageStore != null) {
- File folder = pageStore.getFolder();
- ActiveMQServerLogger.LOGGER.debug("Reading page store " + store + " folder = " + folder);
-
- int pageId = (int) pageStore.getFirstPage();
- for (int i = 0; i < pageStore.getNumberOfPages(); i++) {
- ActiveMQServerLogger.LOGGER.debug("Reading page " + pageId);
- Page page = pageStore.createPage(pageId);
- page.open();
- List<PagedMessage> messages = page.read(storageManager);
- page.close();
-
- int messageId = 0;
-
- for (PagedMessage message : messages) {
- message.initMessage(storageManager);
- long[] queueIDs = message.getQueueIDs();
- List<String> queueNames = new ArrayList<>();
- for (long queueID : queueIDs) {
- PagePosition posCheck = new PagePositionImpl(pageId, messageId);
-
- boolean acked = false;
-
- Set<PagePosition> positions = cursorRecords.get(queueID);
- if (positions != null) {
- acked = positions.contains(posCheck);
- }
-
- if (!acked) {
- PersistentQueueBindingEncoding queueBinding = queueBindings.get(queueID);
- if (queueBinding != null) {
- SimpleString queueName = queueBinding.getQueueName();
- queueNames.add(queueName.toString());
- }
- }
- }
-
- if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID()))) {
- printSingleMessageAsXML(message.getMessage().toCore(), queueNames);
- }
-
- messageId++;
- }
-
- pageId++;
- }
- } else {
- ActiveMQServerLogger.LOGGER.debug("Page store was null");
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private void printSingleMessageAsXML(ICoreMessage message, List<String> queues) throws Exception {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
- printMessageAttributes(message);
- printMessageProperties(message);
- printMessageQueues(queues);
- printMessageBody(message.toCore());
- xmlWriter.writeEndElement(); // end MESSAGES_CHILD
- messagesPrinted++;
- }
-
- private void printMessageBody(Message message) throws Exception {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
-
- if (message.toCore().isLargeMessage()) {
- printLargeMessageBody((LargeServerMessage) message);
- } else {
- xmlWriter.writeCData(XmlDataExporterUtil.encodeMessageBody(message));
- }
- xmlWriter.writeEndElement(); // end MESSAGE_BODY
- }
-
- private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
- LargeBodyEncoder encoder = null;
-
- try {
- encoder = message.toCore().getBodyEncoder();
- encoder.open();
- long totalBytesWritten = 0;
- Long bufferSize;
- long bodySize = encoder.getLargeBodySize();
- for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE) {
- Long remainder = bodySize - totalBytesWritten;
- if (remainder >= LARGE_MESSAGE_CHUNK_SIZE) {
- bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
- } else {
- bufferSize = remainder;
- }
- ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(bufferSize.intValue());
- encoder.encode(buffer, bufferSize.intValue());
- xmlWriter.writeCData(XmlDataExporterUtil.encode(buffer.toByteBuffer().array()));
- totalBytesWritten += bufferSize;
- }
- encoder.close();
- } catch (ActiveMQException e) {
- e.printStackTrace();
- } finally {
- if (encoder != null) {
- try {
- encoder.close();
- } catch (ActiveMQException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- private void printMessageQueues(List<String> queues) throws XMLStreamException {
- xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
- for (String queueName : queues) {
- xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
- }
- xmlWriter.writeEndElement(); // end QUEUES_PARENT
- }
-
- private void printMessageProperties(Message message) throws XMLStreamException {
- xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
- for (SimpleString key : message.getPropertyNames()) {
- Object value = message.getObjectProperty(key);
- xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, XmlDataExporterUtil.convertProperty(value));
-
- // Write the property type as an attribute
- String propertyType = XmlDataExporterUtil.getPropertyType(value);
- if (propertyType != null) {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, propertyType);
- }
- }
- xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
- }
-
- private void printMessageAttributes(ICoreMessage message) throws XMLStreamException {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
- String prettyType = XmlDataExporterUtil.getMessagePrettyType(message.getType());
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
- if (message.getUserID() != null) {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
- }
- }
-
- private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap) {
- List<String> queues = new ArrayList<>();
- for (ReferenceDescribe ref : refMap.values()) {
- queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
- }
- return queues;
- }
-
- // Inner classes -------------------------------------------------
-
- /**
- * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
- */
- static class PrettyPrintHandler implements InvocationHandler {
-
- private final XMLStreamWriter target;
-
- private int depth = 0;
-
- private static final char INDENT_CHAR = ' ';
-
- private static final String LINE_SEPARATOR = System.getProperty("line.separator");
-
- boolean wrap = true;
-
- PrettyPrintHandler(XMLStreamWriter target) {
- this.target = target;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- String m = method.getName();
-
- switch (m) {
- case "writeStartElement":
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
-
- depth++;
- break;
- case "writeEndElement":
- depth--;
- if (wrap) {
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
- }
- wrap = true;
- break;
- case "writeEmptyElement":
- case "writeCData":
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
- break;
- case "writeCharacters":
- wrap = false;
- break;
- }
-
- method.invoke(target, args);
-
- return null;
- }
-
- private String indent(int depth) {
- depth *= 3; // level of indentation
- char[] output = new char[depth];
- while (depth-- > 0) {
- output[depth] = INDENT_CHAR;
- }
- return new String(output);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f82623a2/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java
deleted file mode 100644
index 7711648..0000000
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 org.apache.activemq.artemis.cli.commands.tools;
-
-import com.google.common.base.Preconditions;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.utils.Base64;
-
-/**
- * Common utility methods to help with XML message conversion
- */
-public class XmlDataExporterUtil {
-
- public static String convertProperty(final Object value) {
- if (value instanceof byte[]) {
- return encode((byte[]) value);
- } else {
- return value == null ? XmlDataConstants.NULL : value.toString();
- }
- }
-
- public static String getPropertyType(final Object value) {
- String stringValue = null;
-
- // if the value is null then we can't really know what it is so just set
- // the type to the most generic thing
- if (value == null) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES;
- } else if (value instanceof Boolean) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_BOOLEAN;
- } else if (value instanceof Byte) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_BYTE;
- } else if (value instanceof Short) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_SHORT;
- } else if (value instanceof Integer) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_INTEGER;
- } else if (value instanceof Long) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_LONG;
- } else if (value instanceof Float) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_FLOAT;
- } else if (value instanceof Double) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_DOUBLE;
- } else if (value instanceof String) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_STRING;
- } else if (value instanceof SimpleString) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING;
- } else if (value instanceof byte[]) {
- stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES;
- }
-
- return stringValue;
- }
-
- public static String getMessagePrettyType(byte rawType) {
- String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
-
- if (rawType == Message.BYTES_TYPE) {
- prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
- } else if (rawType == Message.MAP_TYPE) {
- prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
- } else if (rawType == Message.OBJECT_TYPE) {
- prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
- } else if (rawType == Message.STREAM_TYPE) {
- prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
- } else if (rawType == Message.TEXT_TYPE) {
- prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
- }
-
- return prettyType;
- }
-
- /**
- * Base64 encode a ServerMessage body into the proper XML format
- *
- * @param message
- * @return
- */
- public static String encodeMessageBody(final Message message) throws Exception {
- Preconditions.checkNotNull(message, "ServerMessage can not be null");
-
- ActiveMQBuffer byteBuffer = message.toCore().getReadOnlyBodyBuffer();
- byte[] buffer = new byte[byteBuffer.writerIndex()];
- byteBuffer.readBytes(buffer);
-
- return XmlDataExporterUtil.encode(buffer);
- }
-
- protected static String encode(final byte[] data) {
- return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-}