http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/pom.xml b/examples/features/perf/soak/pom.xml new file mode 100644 index 0000000..eb07b0b --- /dev/null +++ b/examples/features/perf/soak/pom.xml @@ -0,0 +1,162 @@ +<?xml version='1.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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <artifactId>artemis-jms-soak-example</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis Soak Normal Example</name> + + <parent> + <groupId>org.apache.activemq.examples.soak</groupId> + <artifactId>perf-root</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-jms-client</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <properties> + <server.dir>${basedir}/server0/</server.dir> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <profiles> + <profile> + <id>server</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>create</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <instance>${basedir}/target/server0</instance> + <configuration>${basedir}/server0</configuration> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.soak</groupId> + <artifactId>artemis-jms-soak-example</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>local</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>runConsumer</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.soak.example.SoakReceiver</clientClass> + </configuration> + </execution> + <execution> + <id>runProducer</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.soak.example.SoakSender</clientClass> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.soak</groupId> + <artifactId>artemis-jms-soak-example</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>remote</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>runConsumer</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.soak.example.SoakReceiver</clientClass> + <args> + <param>tcp://localhost:61616</param> + </args> + </configuration> + </execution> + <execution> + <id>runProducer</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.soak.example.SoakSender</clientClass> + <args> + <param>tcp://localhost:61616</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.soak</groupId> + <artifactId>artemis-jms-soak-example</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> + + </profiles> +</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/server0/broker.xml b/examples/features/perf/soak/server0/broker.xml new file mode 100644 index 0000000..76df21f --- /dev/null +++ b/examples/features/perf/soak/server0/broker.xml @@ -0,0 +1,49 @@ +<?xml version='1.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. +--> +<configuration xmlns="urn:activemq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd"> + <jms xmlns="urn:activemq:jms"> + <queue name="soakQueue"/> + </jms> + <core xmlns="urn:activemq:core"> + <connectors> + <connector name="netty-connector">tcp://localhost:61616?tcpNoDelay=false;tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61616?tcpNoDelay=false;tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</acceptor> + </acceptors> + + <security-enabled>false</security-enabled> + + <persistence-enabled>false</persistence-enabled> + + <server-dump-interval>30000</server-dump-interval> + + <queues> + <queue name="soakQueue"> + <address>soakAddress</address> + </queue> + </queues> + </core> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/soak.properties ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/soak.properties b/examples/features/perf/soak/soak.properties new file mode 100644 index 0000000..2ccff7d --- /dev/null +++ b/examples/features/perf/soak/soak.properties @@ -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. + +duration-in-minutes=2 +num-warmup-messages=100 +message-size=1024 +durable=true +transacted=false +batch-size=1000 +drain-queue=false +destination-lookup=soakQueue +connection-factory-lookup=/ConnectionFactory +throttle-rate=-1 +dups-ok-acknowledge=false +disable-message-id=true +disable-message-timestamp=true http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakBase.java ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakBase.java b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakBase.java new file mode 100644 index 0000000..ce5b9bc --- /dev/null +++ b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakBase.java @@ -0,0 +1,116 @@ +/* + * 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.jms.soak.example; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Properties; +import java.util.Random; +import java.util.logging.Logger; + +public class SoakBase { + + private static final Logger log = Logger.getLogger(SoakBase.class.getName()); + + private static final String DEFAULT_SOAK_PROPERTIES_FILE_NAME = "soak.properties"; + + public static final int TO_MILLIS = 60 * 1000; // from minute to milliseconds + + public static byte[] randomByteArray(final int length) { + byte[] bytes = new byte[length]; + + Random random = new Random(); + + for (int i = 0; i < length; i++) { + bytes[i] = Integer.valueOf(random.nextInt()).byteValue(); + } + + return bytes; + } + + protected static String getPerfFileName() { + String fileName = System.getProperty("soak.props"); + if (fileName == null) { + fileName = SoakBase.DEFAULT_SOAK_PROPERTIES_FILE_NAME; + } + return fileName; + } + + protected static SoakParams getParams(final String fileName) throws Exception { + Properties props = null; + + InputStream is = null; + + try { + is = new FileInputStream(fileName); + + props = new Properties(); + + props.load(is); + } + finally { + if (is != null) { + is.close(); + } + } + + int durationInMinutes = Integer.valueOf(props.getProperty("duration-in-minutes")); + int noOfWarmupMessages = Integer.valueOf(props.getProperty("num-warmup-messages")); + int messageSize = Integer.valueOf(props.getProperty("message-size")); + boolean durable = Boolean.valueOf(props.getProperty("durable")); + boolean transacted = Boolean.valueOf(props.getProperty("transacted")); + int batchSize = Integer.valueOf(props.getProperty("batch-size")); + boolean drainQueue = Boolean.valueOf(props.getProperty("drain-queue")); + String destinationLookup = props.getProperty("destination-lookup"); + String connectionFactoryLookup = props.getProperty("connection-factory-lookup"); + int throttleRate = Integer.valueOf(props.getProperty("throttle-rate")); + boolean dupsOK = Boolean.valueOf(props.getProperty("dups-ok-acknowlege")); + boolean disableMessageID = Boolean.valueOf(props.getProperty("disable-message-id")); + boolean disableTimestamp = Boolean.valueOf(props.getProperty("disable-message-timestamp")); + + SoakBase.log.info("duration-in-minutes: " + durationInMinutes); + SoakBase.log.info("num-warmup-messages: " + noOfWarmupMessages); + SoakBase.log.info("message-size: " + messageSize); + SoakBase.log.info("durable: " + durable); + SoakBase.log.info("transacted: " + transacted); + SoakBase.log.info("batch-size: " + batchSize); + SoakBase.log.info("drain-queue: " + drainQueue); + SoakBase.log.info("throttle-rate: " + throttleRate); + SoakBase.log.info("connection-factory-lookup: " + connectionFactoryLookup); + SoakBase.log.info("destination-lookup: " + destinationLookup); + SoakBase.log.info("disable-message-id: " + disableMessageID); + SoakBase.log.info("disable-message-timestamp: " + disableTimestamp); + SoakBase.log.info("dups-ok-acknowledge: " + dupsOK); + + SoakParams soakParams = new SoakParams(); + soakParams.setDurationInMinutes(durationInMinutes); + soakParams.setNoOfWarmupMessages(noOfWarmupMessages); + soakParams.setMessageSize(messageSize); + soakParams.setDurable(durable); + soakParams.setSessionTransacted(transacted); + soakParams.setBatchSize(batchSize); + soakParams.setDrainQueue(drainQueue); + soakParams.setConnectionFactoryLookup(connectionFactoryLookup); + soakParams.setDestinationLookup(destinationLookup); + soakParams.setThrottleRate(throttleRate); + soakParams.setDisableMessageID(disableMessageID); + soakParams.setDisableTimestamp(disableTimestamp); + soakParams.setDupsOK(dupsOK); + + return soakParams; + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakParams.java ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakParams.java b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakParams.java new file mode 100644 index 0000000..dda2ac1 --- /dev/null +++ b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakParams.java @@ -0,0 +1,158 @@ +/* + * 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.jms.soak.example; + +import java.io.Serializable; + +/** + * Class that holds the parameters used in the performance examples + */ +public class SoakParams implements Serializable { + + private static final long serialVersionUID = -4336539641012356002L; + + private int durationInMinutes = 60; + + private int noOfWarmupMessages; + + private int messageSize = 1024; // in bytes + + private boolean durable = false; + + private boolean isSessionTransacted = false; + + private int batchSize = 5000; + + private boolean drainQueue = true; + + private String connectionFactoryLookup; + + private String destinationLookup; + + private int throttleRate; + + private boolean disableMessageID; + + private boolean disableTimestamp; + + private boolean dupsOK; + + public synchronized int getDurationInMinutes() { + return durationInMinutes; + } + + public synchronized void setDurationInMinutes(final int durationInMinutes) { + this.durationInMinutes = durationInMinutes; + } + + public synchronized int getNoOfWarmupMessages() { + return noOfWarmupMessages; + } + + public synchronized void setNoOfWarmupMessages(final int noOfWarmupMessages) { + this.noOfWarmupMessages = noOfWarmupMessages; + } + + public synchronized int getMessageSize() { + return messageSize; + } + + public synchronized void setMessageSize(final int messageSize) { + this.messageSize = messageSize; + } + + public synchronized boolean isDurable() { + return durable; + } + + public synchronized void setDurable(final boolean durable) { + this.durable = durable; + } + + public synchronized boolean isSessionTransacted() { + return isSessionTransacted; + } + + public synchronized void setSessionTransacted(final boolean isSessionTransacted) { + this.isSessionTransacted = isSessionTransacted; + } + + public synchronized int getBatchSize() { + return batchSize; + } + + public synchronized void setBatchSize(final int batchSize) { + this.batchSize = batchSize; + } + + public synchronized boolean isDrainQueue() { + return drainQueue; + } + + public synchronized void setDrainQueue(final boolean drainQueue) { + this.drainQueue = drainQueue; + } + + public synchronized String getConnectionFactoryLookup() { + return connectionFactoryLookup; + } + + public synchronized void setConnectionFactoryLookup(final String connectionFactoryLookup) { + this.connectionFactoryLookup = connectionFactoryLookup; + } + + public synchronized String getDestinationLookup() { + return destinationLookup; + } + + public synchronized void setDestinationLookup(final String destinationLookup) { + this.destinationLookup = destinationLookup; + } + + public synchronized int getThrottleRate() { + return throttleRate; + } + + public synchronized void setThrottleRate(final int throttleRate) { + this.throttleRate = throttleRate; + } + + public synchronized boolean isDisableMessageID() { + return disableMessageID; + } + + public synchronized void setDisableMessageID(final boolean disableMessageID) { + this.disableMessageID = disableMessageID; + } + + public synchronized boolean isDisableTimestamp() { + return disableTimestamp; + } + + public synchronized void setDisableTimestamp(final boolean disableTimestamp) { + this.disableTimestamp = disableTimestamp; + } + + public synchronized boolean isDupsOK() { + return dupsOK; + } + + public synchronized void setDupsOK(final boolean dupsOK) { + this.dupsOK = dupsOK; + } + +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakReceiver.java ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakReceiver.java b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakReceiver.java new file mode 100644 index 0000000..ce39968 --- /dev/null +++ b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakReceiver.java @@ -0,0 +1,190 @@ +/* + * 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.jms.soak.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.Session; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Logger; + +public class SoakReceiver { + + private static final Logger log = Logger.getLogger(SoakReceiver.class.getName()); + + private static final String EOF = UUID.randomUUID().toString(); + + public static void main(final String[] args) { + Runnable runnable = new Runnable() { + @Override + public void run() { + + try { + String fileName = SoakBase.getPerfFileName(); + + SoakParams params = SoakBase.getParams(fileName); + + final SoakReceiver receiver = new SoakReceiver(params); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + receiver.disconnect(); + } + }); + + receiver.run(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + }; + + Thread t = new Thread(runnable); + t.start(); + } + + private final SoakParams perfParams; + + private final ExceptionListener exceptionListener = new ExceptionListener() { + public void onException(final JMSException e) { + disconnect(); + connect(); + } + }; + + private final MessageListener listener = new MessageListener() { + int modulo = 10000; + + private final AtomicLong count = new AtomicLong(0); + + private final long start = System.currentTimeMillis(); + + long moduloStart = start; + + public void onMessage(final Message msg) { + long totalDuration = System.currentTimeMillis() - start; + + try { + if (SoakReceiver.EOF.equals(msg.getStringProperty("eof"))) { + SoakReceiver.log.info(String.format("Received %s messages in %.2f minutes", count, 1.0 * totalDuration / SoakBase.TO_MILLIS)); + SoakReceiver.log.info("END OF RUN"); + + return; + } + } + catch (JMSException e1) { + e1.printStackTrace(); + } + if (count.incrementAndGet() % modulo == 0) { + double duration = (1.0 * System.currentTimeMillis() - moduloStart) / 1000; + moduloStart = System.currentTimeMillis(); + SoakReceiver.log.info(String.format("received %s messages in %2.2fs (total: %.0fs)", modulo, duration, totalDuration / 1000.0)); + } + } + }; + + private Session session; + + private Connection connection; + + private SoakReceiver(final SoakParams perfParams) { + this.perfParams = perfParams; + } + + public void run() throws Exception { + connect(); + + boolean runInfinitely = perfParams.getDurationInMinutes() == -1; + + if (!runInfinitely) { + Thread.sleep(perfParams.getDurationInMinutes() * SoakBase.TO_MILLIS); + + // send EOF message + Message eof = session.createMessage(); + eof.setStringProperty("eof", SoakReceiver.EOF); + listener.onMessage(eof); + + if (connection != null) { + connection.close(); + connection = null; + } + } + else { + while (true) { + Thread.sleep(500); + } + } + } + + private void disconnect() { + if (connection != null) { + try { + connection.setExceptionListener(null); + connection.close(); + } + catch (JMSException e) { + e.printStackTrace(); + } + finally { + connection = null; + } + } + } + + private void connect() { + InitialContext ic = null; + try { + ic = new InitialContext(); + + ConnectionFactory factory = (ConnectionFactory) ic.lookup(perfParams.getConnectionFactoryLookup()); + + Destination destination = (Destination) ic.lookup(perfParams.getDestinationLookup()); + + connection = factory.createConnection(); + connection.setExceptionListener(exceptionListener); + + session = connection.createSession(perfParams.isSessionTransacted(), perfParams.isDupsOK() ? Session.DUPS_OK_ACKNOWLEDGE : Session.AUTO_ACKNOWLEDGE); + + MessageConsumer messageConsumer = session.createConsumer(destination); + messageConsumer.setMessageListener(listener); + + connection.start(); + } + catch (Exception e) { + e.printStackTrace(); + } + finally { + try { + ic.close(); + } + catch (NamingException e) { + e.printStackTrace(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakSender.java ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakSender.java b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakSender.java new file mode 100644 index 0000000..10fbbd8 --- /dev/null +++ b/examples/features/perf/soak/src/main/java/org/apache/activemq/artemis/jms/soak/example/SoakSender.java @@ -0,0 +1,195 @@ +/* + * 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.jms.soak.example; + +import javax.jms.BytesMessage; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Logger; + +import org.apache.activemq.artemis.utils.TokenBucketLimiter; +import org.apache.activemq.artemis.utils.TokenBucketLimiterImpl; + +public class SoakSender { + + private static final Logger log = Logger.getLogger(SoakSender.class.getName()); + + public static void main(final String[] args) { + try { + String fileName = SoakBase.getPerfFileName(); + + SoakParams params = SoakBase.getParams(fileName); + final SoakSender sender = new SoakSender(params); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + sender.disconnect(); + } + }); + + sender.run(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private final SoakParams perfParams; + + private Connection connection; + + private Session session; + + private MessageProducer producer; + + private final ExceptionListener exceptionListener = new ExceptionListener() { + public void onException(final JMSException e) { + System.out.println("SoakReconnectableSender.exceptionListener.new ExceptionListener() {...}.onException()"); + disconnect(); + connect(); + } + + }; + + private SoakSender(final SoakParams perfParams) { + this.perfParams = perfParams; + } + + public void run() throws Exception { + connect(); + + boolean runInfinitely = perfParams.getDurationInMinutes() == -1; + + BytesMessage message = session.createBytesMessage(); + + byte[] payload = SoakBase.randomByteArray(perfParams.getMessageSize()); + + message.writeBytes(payload); + + final int modulo = 10000; + + TokenBucketLimiter tbl = perfParams.getThrottleRate() != -1 ? new TokenBucketLimiterImpl(perfParams.getThrottleRate(), false) : null; + + boolean transacted = perfParams.isSessionTransacted(); + int txBatchSize = perfParams.getBatchSize(); + boolean display = true; + + long start = System.currentTimeMillis(); + long moduleStart = start; + AtomicLong count = new AtomicLong(0); + while (true) { + try { + producer.send(message); + count.incrementAndGet(); + + if (transacted) { + if (count.longValue() % txBatchSize == 0) { + session.commit(); + } + } + + long totalDuration = System.currentTimeMillis() - start; + + if (display && count.longValue() % modulo == 0) { + double duration = (1.0 * System.currentTimeMillis() - moduleStart) / 1000; + moduleStart = System.currentTimeMillis(); + SoakSender.log.info(String.format("sent %s messages in %2.2fs (time: %.0fs)", modulo, duration, totalDuration / 1000.0)); + } + + if (tbl != null) { + tbl.limit(); + } + + if (!runInfinitely && totalDuration > perfParams.getDurationInMinutes() * SoakBase.TO_MILLIS) { + break; + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + SoakSender.log.info(String.format("Sent %s messages in %s minutes", count, perfParams.getDurationInMinutes())); + SoakSender.log.info("END OF RUN"); + + if (connection != null) { + connection.close(); + connection = null; + } + } + + private synchronized void disconnect() { + if (connection != null) { + try { + connection.setExceptionListener(null); + connection.close(); + } + catch (JMSException e) { + e.printStackTrace(); + } + finally { + connection = null; + } + } + } + + private void connect() { + InitialContext ic = null; + try { + ic = new InitialContext(); + + ConnectionFactory factory = (ConnectionFactory) ic.lookup(perfParams.getConnectionFactoryLookup()); + + Destination destination = (Destination) ic.lookup(perfParams.getDestinationLookup()); + + connection = factory.createConnection(); + + session = connection.createSession(perfParams.isSessionTransacted(), perfParams.isDupsOK() ? Session.DUPS_OK_ACKNOWLEDGE : Session.AUTO_ACKNOWLEDGE); + + producer = session.createProducer(destination); + + producer.setDeliveryMode(perfParams.isDurable() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); + + producer.setDisableMessageID(perfParams.isDisableMessageID()); + + producer.setDisableMessageTimestamp(perfParams.isDisableTimestamp()); + + connection.setExceptionListener(exceptionListener); + } + catch (Exception e) { + e.printStackTrace(); + } + finally { + try { + ic.close(); + } + catch (NamingException e) { + e.printStackTrace(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/perf/soak/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/perf/soak/src/main/resources/jndi.properties b/examples/features/perf/soak/src/main/resources/jndi.properties new file mode 100644 index 0000000..93537c4 --- /dev/null +++ b/examples/features/perf/soak/src/main/resources/jndi.properties @@ -0,0 +1,20 @@ +# 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. + +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +connectionFactory.ConnectionFactory=tcp://localhost:61616 +queue.queue/exampleQueue=exampleQueue http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/pom.xml b/examples/features/pom.xml new file mode 100644 index 0000000..f5afbee --- /dev/null +++ b/examples/features/pom.xml @@ -0,0 +1,68 @@ +<?xml version='1.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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.activemq.examples</groupId> + <artifactId>artemis-examples</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <groupId>org.apache.activemq.examples.clustered</groupId> + <artifactId>broker-features</artifactId> + <packaging>pom</packaging> + <name>ActiveMQ Artemis Clustered Examples</name> + + <!-- Properties --> + <properties> + <!-- + Explicitly declaring the source encoding eliminates the following + message: [WARNING] Using platform encoding (UTF-8 actually) to copy + filtered resources, i.e. build is platform dependent! + --> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <activemq.basedir>${project.basedir}/../..</activemq.basedir> + </properties> + + <profiles> + <profile> + <id>examples</id> + <modules> + <module>clustered</module> + <module>ha</module> + <module>standard</module> + <module>sub-modules</module> + <module>perf</module> + </modules> + </profile> + <profile> + <id>release</id> + <modules> + <module>clustered</module> + <module>ha</module> + <module>standard</module> + <module>sub-modules</module> + <module>perf</module> + </modules> + </profile> + </profiles> +</project> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/README.md ---------------------------------------------------------------------- diff --git a/examples/features/standard/README.md b/examples/features/standard/README.md new file mode 100644 index 0000000..e9d9e36 --- /dev/null +++ b/examples/features/standard/README.md @@ -0,0 +1,32 @@ +Running the ActiveMQ Artemis Examples +============================ + +To run an individual example firstly cd into the example directory and run + +```sh +mvn verify +``` + +Most examples offer a way to start them without creating and starting the server (say if you want to do it manually) + +```sh +mvn verify -PnoServer +``` + +If you are running against an un released version, i.e. from master branch, you will have to run `mvn install` on the root +pom.xml and the example/activemq-jms-examples-common/pom.xml first. + +If you want to run all the examples (except those that need to be run standalone) you can run `mvn verify -Pexamples` in the examples +directory but before you do you will need to up the memory used by running: + +``` +export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m" +``` +### Recreating the examples + +If you are trying to copy the examples somewhere else and modifying them. Consider asking Maven to explicitly list all the dependencies: + +``` +# if trying to modify the 'topic' example: +cd examples/jms/topic && mvn dependency:list +``` http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/pom.xml b/examples/features/standard/bridge/pom.xml new file mode 100644 index 0000000..db1caf8 --- /dev/null +++ b/examples/features/standard/bridge/pom.xml @@ -0,0 +1,167 @@ +<?xml version='1.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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>jms-examples</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>core-bridge</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis Core Bridge Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jms_2.0_spec</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>create0</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <libList> + <!-- For the transformer --> + <arg>org.apache.activemq.examples.broker:core-bridge:${project.version}</arg> + </libList> + <ignore>${noServer}</ignore> + <instance>${basedir}/target/server0</instance> + <configuration>${basedir}/target/classes/activemq/server0</configuration> + </configuration> + </execution> + <execution> + <id>create1</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <libList> + <!-- For the transformer --> + <arg>org.apache.activemq.examples.broker:core-bridge:${project.version}</arg> + </libList> + <ignore>${noServer}</ignore> + <instance>${basedir}/target/server1</instance> + <configuration>${basedir}/target/classes/activemq/server1</configuration> + <portOffset>1</portOffset> + </configuration> + </execution> + <execution> + <id>start0</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server0</location> + <testURI>tcp://localhost:61616</testURI> + <args> + <param>run</param> + </args> + <name>server0</name> + </configuration> + </execution> + <execution> + <id>start1</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <spawn>true</spawn> + <location>${basedir}/target/server1</location> + <testURI>tcp://localhost:61617</testURI> + <args> + <param>run</param> + </args> + <name>server1</name> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.BridgeExample</clientClass> + </configuration> + </execution> + <execution> + <id>stop0</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <location>${basedir}/target/server0</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + <execution> + <id>stop1</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <location>${basedir}/target/server1</location> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>core-bridge</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/readme.html b/examples/features/standard/bridge/readme.html new file mode 100644 index 0000000..698c6c2 --- /dev/null +++ b/examples/features/standard/bridge/readme.html @@ -0,0 +1,74 @@ +<!-- +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. +--> + +<html> + <head> + <title>ActiveMQ Artemis Core Bridge Example</title> + <link rel="stylesheet" type="text/css" href="../../../common/common.css" /> + <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" /> + <script type="text/javascript" src="../../../common/prettify.js"></script> + </head> + <body onload="prettyPrint()"> + <h1>Core Bridge Example</h1> + <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre> + + <p>This example demonstrates a core bridge deployed on one server, which consumes messages from a + local queue and forwards them to an address on a second server.</p> + + <p>Core bridges are used to create message flows between any two ActiveMQ Artemis servers which are remotely separated. + Core bridges are resilient and will cope with temporary connection failure allowing them to be an ideal + choice for forwarding over unreliable connections, e.g. a WAN.</p> + <p>They can also be configured with an optional filter expression, and will only forward messages that + match that filter.</p> + <p>Furthermore they can be configured to use an optional Transformer class. A user-defined Transformer class + can be specified which is called at forwarding time. This gives the user the opportunity to transform + the message in some ways, e.g. changing its properties or body</p> + <p>ActiveMQ Artemis also includes a <b>JMS Bridge</b>. This is similar to a core bridge, but uses the JMS API + and can be used to bridge between any two JMS 1.1 compliant messaging systems. The core bridge is limited to bridging + between ActiveMQ Artemis instances, but may provide better performance than the JMS bridge. The JMS bridge is covered in + a separate example.</p> + <p>For more information on bridges, please see the ActiveMQ Artemis user manual.</p> + + <p>In this example we will demonstrate a simple sausage factory for aardvarks.</p> + <p>We have a JMS queue on server 0 named <code>sausage-factory</code>, and we have a + JMS queue on server 1 named <code>mincing-machine</code></p> + <p>We want to forward any messages that are sent to the <code>sausage-factory</code> queue on server 0, to the <code>mincing-machine</code> + on server 1.</p> + <p>We only want to make aardvark sausages, so we only forward messages where the property "name" is set + to "aardvark". It is known that other things, such are Sasquatches are also sent to the <code>sausage-factory</code> and we + want to reject those.</p> + <p>Moreover it is known that Aardvarks normally wear blue hats, and it's important that we only make sausages using + Aardvarks with green hats, so on the way we are going transform the property "hat" from "green" to "blue".</p> + <p>Here's a snippet from <code>broker.xml</code> showing the bridge configuration</p> + <pre class="prettyprint"> + <code> + <bridge name="my-bridge"> + <queue-name>jms.queue.sausage-factory</queue-name> + <forwarding-address>jms.queue.mincing-machine</forwarding-address> + <filter string="name='aardvark'"/> + <transformer-class-name>org.apache.activemq.artemis.jms.example.HatColourChangeTransformer</transformer-class-name> + <reconnect-attempts>-1</reconnect-attempts> + <static-connectors> + <connector-ref>remote-connector</connector-ref> + </static-connectors> + </bridge> + </code> + </pre> + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/BridgeExample.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/BridgeExample.java b/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/BridgeExample.java new file mode 100644 index 0000000..0fa17c2 --- /dev/null +++ b/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/BridgeExample.java @@ -0,0 +1,175 @@ +/* + * 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.jms.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.naming.InitialContext; +import java.util.Hashtable; + +/** + * This example demonstrates a core bridge set-up between two nodes, consuming messages from a queue + * on one node and forwarding them to an address on the second node. + */ +public class BridgeExample { + + public static void main(final String[] args) throws Exception { + Connection connection0 = null; + + Connection connection1 = null; + + InitialContext ic0 = null; + + InitialContext ic1 = null; + + try { + // Step 1 - we create an initial context for looking up JNDI on node 0 + + Hashtable<String, Object> properties = new Hashtable<String, Object>(); + properties.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory"); + properties.put("connectionFactory.ConnectionFactory", "tcp://127.0.0.1:61616"); + properties.put("queue.queue/sausage-factory", "sausage-factory"); + ic0 = new InitialContext(properties); + + // Step 2 - we look up the sausage-factory queue from node 0 + + Queue sausageFactory = (Queue) ic0.lookup("queue/sausage-factory"); + + // Step 3 - we look up a JMS ConnectionFactory object from node 0 + + ConnectionFactory cf0 = (ConnectionFactory) ic0.lookup("ConnectionFactory"); + + // Step 4 - we create an initial context for looking up JNDI on node 1 + + properties = new Hashtable<String, Object>(); + properties.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory"); + properties.put("connectionFactory.ConnectionFactory", "tcp://127.0.0.1:61617"); + properties.put("queue.queue/mincing-machine", "mincing-machine"); + ic1 = new InitialContext(properties); + + // Step 5 - we look up the mincing-machine queue on node 1 + + Queue mincingMachine = (Queue) ic1.lookup("queue/mincing-machine"); + + // Step 6 - we look up a JMS ConnectionFactory object from node 1 + + ConnectionFactory cf1 = (ConnectionFactory) ic1.lookup("ConnectionFactory"); + + // Step 7. We create a JMS Connection connection0 which is a connection to server 0 + + connection0 = cf0.createConnection(); + + // Step 8. We create a JMS Connection connection1 which is a connection to server 1 + connection1 = cf1.createConnection(); + + // Step 9. We create a JMS Session on server 0 + + Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 10. We create a JMS Session on server 1 + + Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 10. We start the connection to ensure delivery occurs on them + + connection1.start(); + + // Step 11. We create JMS MessageConsumer object + MessageConsumer consumer = session1.createConsumer(mincingMachine); + + // Step 12. We create a JMS MessageProducer object on server 0 + MessageProducer producer = session0.createProducer(sausageFactory); + + // Step 13. We create and send a message representing an aardvark with a green hat to the sausage-factory + // on node 0 + Message message = session0.createMessage(); + + message.setStringProperty("name", "aardvark"); + + message.setStringProperty("hat", "green"); + + producer.send(message); + + System.out.println("Sent " + message.getStringProperty("name") + + " message with " + + message.getStringProperty("hat") + + " hat to sausage-factory on node 0"); + + // Step 14 - we successfully receive the aardvark message from the mincing-machine one node 1. The aardvark's + // hat is now blue since it has been transformed! + + Message receivedMessage = consumer.receive(5000); + + System.out.println("Received " + receivedMessage.getStringProperty("name") + + " message with " + + receivedMessage.getStringProperty("hat") + + " hat from mincing-machine on node 1"); + + // Step 13. We create and send another message, this time representing a sasquatch with a mauve hat to the + // sausage-factory on node 0. This won't be bridged to the mincing-machine since we only want aardvarks, not + // sasquatches + + message = session0.createMessage(); + + message.setStringProperty("name", "sasquatch"); + + message.setStringProperty("hat", "mauve"); + + producer.send(message); + + System.out.println("Sent " + message.getStringProperty("name") + + " message with " + + message.getStringProperty("hat") + + " hat to sausage-factory on node 0"); + + // Step 14. We don't receive the message since it has not been bridged. + + receivedMessage = consumer.receive(1000); + + if (receivedMessage == null) { + System.out.println("Didn't receive that message from mincing-machine on node 1"); + } + else { + throw new IllegalStateException(); + } + } + finally { + // Step 15. Be sure to close our resources! + + if (connection0 != null) { + connection0.close(); + } + + if (connection1 != null) { + connection1.close(); + } + + if (ic0 != null) { + ic0.close(); + } + + if (ic1 != null) { + ic1.close(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/HatColourChangeTransformer.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/HatColourChangeTransformer.java b/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/HatColourChangeTransformer.java new file mode 100644 index 0000000..ae8cf39 --- /dev/null +++ b/examples/features/standard/bridge/src/main/java/org/apache/activemq/artemis/jms/example/HatColourChangeTransformer.java @@ -0,0 +1,38 @@ +/* + * 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.jms.example; + +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.server.ServerMessage; +import org.apache.activemq.artemis.core.server.cluster.Transformer; + +public class HatColourChangeTransformer implements Transformer { + + public ServerMessage transform(final ServerMessage message) { + SimpleString propName = new SimpleString("hat"); + + SimpleString oldProp = message.getSimpleStringProperty(propName); + + // System.out.println("Old hat colour is " + oldProp); + + // Change the colour + message.putStringProperty(propName, new SimpleString("blue")); + + return message; + } + +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/bridge/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..250a851 --- /dev/null +++ b/examples/features/standard/bridge/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,88 @@ +<?xml version='1.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. +--> + +<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:activemq" + xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd"> + <jms xmlns="urn:activemq:jms"> + <!--the queue used by the example--> + <queue name="sausage-factory"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <bindings-directory>${data.dir}/server0/data/messaging/bindings</bindings-directory> + + <journal-directory>${data.dir}/server0/data/messaging/journal</journal-directory> + + <large-messages-directory>${data.dir}/server0/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${data.dir}/server0/data/messaging/paging</paging-directory> + + <!-- Connectors --> + <connectors> + <!-- Connector to the other node --> + <connector name="remote-connector">tcp://localhost:61617</connector> + </connectors> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor> + </acceptors> + + <!-- We need to create a core queue for the JMS queue explicitly because the bridge will be deployed + before the JMS queue is deployed, so the first time, it otherwise won't find the queue --> + <queues> + <queue name="jms.queue.sausage-factory"> + <address>jms.queue.sausage-factory</address> + </queue> + </queues> + + <!-- We set-up a bridge that forwards from a queue on this node to an address on another node. + We specify a filter with the bridge, and a transformer too. The filter and transformer are optional --> + <bridges> + <bridge name="my-bridge"> + <queue-name>jms.queue.sausage-factory</queue-name> + <forwarding-address>jms.queue.mincing-machine</forwarding-address> + <filter string="name='aardvark'"/> + <transformer-class-name>org.apache.activemq.artemis.jms.example.HatColourChangeTransformer</transformer-class-name> + <reconnect-attempts>-1</reconnect-attempts> + <static-connectors> + <connector-ref>remote-connector</connector-ref> + </static-connectors> + </bridge> + </bridges> + + <!-- Other config --> + + <security-settings> + <!--security for example queue--> + <security-setting match="jms.queue.#"> + <permission type="createDurableQueue" roles="guest"/> + <permission type="deleteDurableQueue" roles="guest"/> + <permission type="createNonDurableQueue" roles="guest"/> + <permission type="deleteNonDurableQueue" roles="guest"/> + <permission type="consume" roles="guest"/> + <permission type="send" roles="guest"/> + </security-setting> + </security-settings> + </core> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/bridge/src/main/resources/activemq/server1/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/bridge/src/main/resources/activemq/server1/broker.xml b/examples/features/standard/bridge/src/main/resources/activemq/server1/broker.xml new file mode 100644 index 0000000..516f179 --- /dev/null +++ b/examples/features/standard/bridge/src/main/resources/activemq/server1/broker.xml @@ -0,0 +1,59 @@ +<?xml version='1.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. +--> + +<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:activemq" + xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd"> + + <jms xmlns="urn:activemq:jms"> + <!--the queue used by the example--> + <queue name="mincing-machine"/> + </jms> + <core xmlns="urn:activemq:core"> + + <bindings-directory>${data.dir}/server1/data/messaging/bindings</bindings-directory> + + <journal-directory>${data.dir}/server1/data/messaging/journal</journal-directory> + + <large-messages-directory>${data.dir}/server1/data/messaging/largemessages</large-messages-directory> + + <paging-directory>${data.dir}/server1/data/messaging/paging</paging-directory> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61617</acceptor> + </acceptors> + + <!-- Other config --> + + <security-settings> + <!--security for example queue--> + <security-setting match="jms.queue.#"> + <permission type="createDurableQueue" roles="guest"/> + <permission type="deleteDurableQueue" roles="guest"/> + <permission type="createNonDurableQueue" roles="guest"/> + <permission type="deleteNonDurableQueue" roles="guest"/> + <permission type="consume" roles="guest"/> + <permission type="send" roles="guest"/> + </security-setting> + </security-settings> + </core> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/browser/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/browser/pom.xml b/examples/features/standard/browser/pom.xml new file mode 100644 index 0000000..7ab1299 --- /dev/null +++ b/examples/features/standard/browser/pom.xml @@ -0,0 +1,110 @@ +<?xml version='1.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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>jms-examples</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>browser</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Browser Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-jms-client</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>create</id> + <phase>verify</phase> + <configuration> + <ignore>${noServer}</ignore> + </configuration> + <goals> + <goal>create</goal> + </goals> + </execution> + <execution> + <id>start</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <spawn>true</spawn> + <ignore>${noServer}</ignore> + <testURI>tcp://localhost:61616</testURI> + <args> + <param>run</param> + </args> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.QueueBrowserExample</clientClass> + </configuration> + </execution> + <execution> + <id>stop</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>browser</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/browser/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/standard/browser/readme.html b/examples/features/standard/browser/readme.html new file mode 100644 index 0000000..9f9e01a --- /dev/null +++ b/examples/features/standard/browser/readme.html @@ -0,0 +1,40 @@ +<!-- +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. +--> + +<html> + <head> + <title>ActiveMQ Artemis JMS QueueBrowser Example</title> + <link rel="stylesheet" type="text/css" href="../../../common/common.css" /> + <link rel="stylesheet" type="text/css" href="../../../common/prettify.css" /> + <script type="text/javascript" src="../../../common/prettify.js"></script> + </head> + <body onload="prettyPrint()"> + <h1>JMS QueueBrowser Example</h1> + <pre>To run the example, simply type <b>mvn verify</b> from this directory, <br>or <b>mvn -PnoServer verify</b> if you want to start and create the server manually.</pre> + + <p>This example shows you how to use a JMS <a href="http://java.sun.com/javaee/5/docs/api/javax/jms/QueueBrowser.html">QueueBrowser</a> with ActiveMQ Artemis.<br /> + Queues are a standard part of JMS, please consult the JMS 1.1 specification for full details.<br /> + A QueueBrowser is used to look at messages on the queue without removing them. + It can scan the entire content of a queue or only messages matching a message selector.</p> + <p> + The example will send 2 messages on a queue, use a QueueBrowser to browse + the queue (looking at the message without removing them) and finally consume the 2 messages + </p> + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/browser/src/main/java/org/apache/activemq/artemis/jms/example/QueueBrowserExample.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/browser/src/main/java/org/apache/activemq/artemis/jms/example/QueueBrowserExample.java b/examples/features/standard/browser/src/main/java/org/apache/activemq/artemis/jms/example/QueueBrowserExample.java new file mode 100644 index 0000000..1c9db3b --- /dev/null +++ b/examples/features/standard/browser/src/main/java/org/apache/activemq/artemis/jms/example/QueueBrowserExample.java @@ -0,0 +1,103 @@ +/* + * 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.jms.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.QueueBrowser; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; +import java.util.Enumeration; + +/** + * A simple example which shows how to use a QueueBrowser to look at messages of a queue without removing them from the queue + */ +public class QueueBrowserExample { + + public static void main(final String[] args) throws Exception { + Connection connection = null; + InitialContext initialContext = null; + try { + // Step 1. Create an initial context to perform the JNDI lookup. + initialContext = new InitialContext(); + + // Step 2. Perfom a lookup on the queue + Queue queue = (Queue) initialContext.lookup("queue/exampleQueue"); + + // Step 3. Perform a lookup on the Connection Factory + // you could alternatively instantiate the connection directly + // ConnectionFactory cf = new ActiveMQConnectionFactory(); // this would accept the broker URI as well + ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + + // Step 4. Create a JMS Connection + connection = cf.createConnection(); + + // Step 5. Create a JMS Session + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Step 6. Create a JMS Message Producer + MessageProducer producer = session.createProducer(queue); + + // Step 7. Create 2 Text Messages + TextMessage message_1 = session.createTextMessage("this is the 1st message"); + TextMessage message_2 = session.createTextMessage("this is the 2nd message"); + + // Step 8. Send the Message + producer.send(message_1); + producer.send(message_2); + + // Step 9. Create the JMS QueueBrowser + QueueBrowser browser = session.createBrowser(queue); + + // Step 10. Browse the messages on the queue + // Browsing a queue does not remove the messages from the queue + Enumeration messageEnum = browser.getEnumeration(); + while (messageEnum.hasMoreElements()) { + TextMessage message = (TextMessage) messageEnum.nextElement(); + System.out.println("Browsing: " + message.getText()); + } + + // Step 11. Close the browser + browser.close(); + + // Step 12. Create a JMS Message Consumer + MessageConsumer messageConsumer = session.createConsumer(queue); + + // Step 13. Start the Connection + connection.start(); + + // Step 14. Receive the 2 messages + TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000); + System.out.println("Received message: " + messageReceived.getText()); + messageReceived = (TextMessage) messageConsumer.receive(5000); + System.out.println("Received message: " + messageReceived.getText()); + } + finally { + // Step 15. Be sure to close our JMS resources! + if (initialContext != null) { + initialContext.close(); + } + if (connection != null) { + connection.close(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/browser/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/browser/src/main/resources/jndi.properties b/examples/features/standard/browser/src/main/resources/jndi.properties new file mode 100644 index 0000000..93537c4 --- /dev/null +++ b/examples/features/standard/browser/src/main/resources/jndi.properties @@ -0,0 +1,20 @@ +# 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. + +java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory +connectionFactory.ConnectionFactory=tcp://localhost:61616 +queue.queue/exampleQueue=exampleQueue http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/client-kickoff/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/client-kickoff/pom.xml b/examples/features/standard/client-kickoff/pom.xml new file mode 100644 index 0000000..6ffb19a --- /dev/null +++ b/examples/features/standard/client-kickoff/pom.xml @@ -0,0 +1,112 @@ +<?xml version='1.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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>jms-examples</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + + <artifactId>client-kickoff</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Kick Off Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-jms-client</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-maven-plugin</artifactId> + <executions> + <execution> + <id>create</id> + <goals> + <goal>create</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <!-- options used for JMX on the example --> + <javaOptions>-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=3000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false + </javaOptions> + </configuration> + </execution> + <execution> + <id>start</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <spawn>true</spawn> + <testURI>tcp://localhost:61616</testURI> + <args> + <param>run</param> + </args> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.ClientKickoffExample</clientClass> + </configuration> + </execution> + <execution> + <id>stop</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>client-kickoff</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + +</project>