http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/java/PushReg.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/java/PushReg.java b/examples/features/standard/rest/push/src/main/java/PushReg.java new file mode 100644 index 0000000..2567826 --- /dev/null +++ b/examples/features/standard/rest/push/src/main/java/PushReg.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.activemq.artemis.rest.queue.push.xml.Authentication; +import org.apache.activemq.artemis.rest.queue.push.xml.BasicAuth; +import org.apache.activemq.artemis.rest.queue.push.xml.PushRegistration; +import org.apache.activemq.artemis.rest.queue.push.xml.XmlLink; +import org.jboss.resteasy.client.ClientRequest; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.spi.Link; + +public class PushReg { + + public static void main(String[] args) throws Exception { + // get the push consumers factory resource + ClientRequest request = new ClientRequest("http://localhost:9095/queues/jms.queue.orders"); + ClientResponse res = request.head(); + Link pushConsumers = res.getHeaderAsLink("msg-push-consumers"); + + // next create the XML document that represents the registration + // Really, just create a link with the shipping URL and the type you want posted + PushRegistration reg = new PushRegistration(); + BasicAuth authType = new BasicAuth(); + authType.setUsername("guest"); + authType.setPassword("guest"); + Authentication auth = new Authentication(); + auth.setType(authType); + reg.setAuthenticationMechanism(auth); + XmlLink target = new XmlLink(); + target.setHref("http://localhost:9095/queues/jms.queue.shipping"); + target.setType("application/xml"); + target.setRelationship("destination"); + reg.setTarget(target); + + res = pushConsumers.request().body("application/xml", reg).post(); + System.out.println("Create push registration. Resource URL: " + res.getLocationLink().getHref()); + } +}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/java/ReceiveShipping.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/java/ReceiveShipping.java b/examples/features/standard/rest/push/src/main/java/ReceiveShipping.java new file mode 100644 index 0000000..80a3892 --- /dev/null +++ b/examples/features/standard/rest/push/src/main/java/ReceiveShipping.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.activemq.artemis.jms.client.ActiveMQDestination; +import org.apache.activemq.artemis.rest.Jms; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.Session; + +public class ReceiveShipping { + + public static void main(String[] args) throws Exception { + ConnectionFactory factory = JmsHelper.createConnectionFactory("activemq-client.xml"); + Destination destination = (ActiveMQDestination) ActiveMQDestination.fromAddress("jms.queue.shipping"); + + Connection conn = factory.createConnection(); + try { + Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer consumer = session.createConsumer(destination); + consumer.setMessageListener(new MessageListener() { + @Override + public void onMessage(Message message) { + System.out.println("Received Message: "); + Order order = Jms.getEntity(message, Order.class); + System.out.println(order); + } + }); + conn.start(); + Thread.sleep(1000000); + } + finally { + conn.close(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/resources/activemq-client.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/resources/activemq-client.xml b/examples/features/standard/rest/push/src/main/resources/activemq-client.xml new file mode 100644 index 0000000..6fe4547 --- /dev/null +++ b/examples/features/standard/rest/push/src/main/resources/activemq-client.xml @@ -0,0 +1,36 @@ +<?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"> + </jms> + + <core xmlns="urn:activemq:core"> + + <!-- Connectors --> + <connectors> + <connector name="netty-connector">tcp://localhost:61616</connector> + </connectors> + </core> + +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/resources/artemis-roles.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/resources/artemis-roles.properties b/examples/features/standard/rest/push/src/main/resources/artemis-roles.properties new file mode 100644 index 0000000..4e2d44c --- /dev/null +++ b/examples/features/standard/rest/push/src/main/resources/artemis-roles.properties @@ -0,0 +1,17 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +guest=guest \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/resources/artemis-users.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/resources/artemis-users.properties b/examples/features/standard/rest/push/src/main/resources/artemis-users.properties new file mode 100644 index 0000000..4e2d44c --- /dev/null +++ b/examples/features/standard/rest/push/src/main/resources/artemis-users.properties @@ -0,0 +1,17 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +guest=guest \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/resources/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/resources/broker.xml b/examples/features/standard/rest/push/src/main/resources/broker.xml new file mode 100644 index 0000000..13f2f23 --- /dev/null +++ b/examples/features/standard/rest/push/src/main/resources/broker.xml @@ -0,0 +1,60 @@ +<?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 queues used by the example--> + <queue name="orders"/> + <queue name="shipping"/> + </jms> + + <core xmlns="urn:activemq:core"> + + <persistence-enabled>false</persistence-enabled> + <!-- Connectors --> + + <connectors> + <connector name="in-vm">vm://0</connector> + </connectors> + + <acceptors> + <acceptor name="in-vm">vm://0</acceptor> + <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor> + </acceptors> + + <!-- Other config --> + + <security-settings> + <!--security for example queue--> + <security-setting match="#"> + <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/rest/push/src/main/resources/test-realm.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/resources/test-realm.properties b/examples/features/standard/rest/push/src/main/resources/test-realm.properties new file mode 100644 index 0000000..65f2dd9 --- /dev/null +++ b/examples/features/standard/rest/push/src/main/resources/test-realm.properties @@ -0,0 +1,18 @@ +# 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. + +guest: guest,admin http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/rest/push/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/rest/push/src/main/webapp/WEB-INF/web.xml b/examples/features/standard/rest/push/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..d4ba92b --- /dev/null +++ b/examples/features/standard/rest/push/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,70 @@ +<?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. +--> + +<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + + <filter> + <filter-name>Rest-Messaging</filter-name> + <filter-class> + org.jboss.resteasy.plugins.server.servlet.FilterDispatcher + </filter-class> + </filter> + + <filter-mapping> + <filter-name>Rest-Messaging</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <listener> + <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> + </listener> + + <listener> + <listener-class>org.apache.activemq.rest.integration.ActiveMQBootstrapListener</listener-class> + </listener> + + <listener> + <listener-class>org.apache.activemq.rest.integration.RestMessagingBootstrapListener</listener-class> + </listener> + + <security-constraint> + <web-resource-collection> + <web-resource-name>Resteasy</web-resource-name> + <url-pattern>/queues/jms.queue.shipping/*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>admin</role-name> + </auth-constraint> + </security-constraint> + + <login-config> + <auth-method>BASIC</auth-method> + <realm-name>Test</realm-name> + </login-config> + + <security-role> + <role-name>admin</role-name> + </security-role> + +</web-app> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/scheduled-message/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/scheduled-message/pom.xml b/examples/features/standard/scheduled-message/pom.xml new file mode 100644 index 0000000..7447f33 --- /dev/null +++ b/examples/features/standard/scheduled-message/pom.xml @@ -0,0 +1,114 @@ +<?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>scheduled-message</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Scheduled Message Example</name> + + <properties> + <activemq.basedir>${project.basedir}/../../../..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>artemis-core-client</artifactId> + <version>${project.version}</version> + </dependency> + <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> + </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.ScheduledMessageExample</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>scheduled-message</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/scheduled-message/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/standard/scheduled-message/readme.html b/examples/features/standard/scheduled-message/readme.html new file mode 100644 index 0000000..9144f94 --- /dev/null +++ b/examples/features/standard/scheduled-message/readme.html @@ -0,0 +1,134 @@ +<!-- +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 Scheduled Message 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 Scheduled Message 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 send a scheduled message to a JMS Queue using ActiveMQ Artemis.</p> + <p>A Scheduled Message is a message that will be delivered at a time specified by the sender. To do this, + simply set a HDR_SCHEDULED_DELIVERY_TIME header property. The value of the property should be the time of + delivery in milliseconds. </p> + + <p>In this example, a message is created with the scheduled delivery time set to 5 seconds after the current time.</p> + + + <h2>Example step-by-step</h2> + <p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p> + + <ol> + <li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li> + <pre class="prettyprint"> + <code>InitialContext initialContext = getContext();</code> + </pre> + + <li>We look-up the JMS queue object from JNDI</li> + <pre class="prettyprint"> + <code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code> + </pre> + + <li>We look-up the JMS connection factory object from JNDI</li> + <pre class="prettyprint"> + <code>ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");</code> + </pre> + + <li>We create a JMS connection</li> + <pre class="prettyprint"> + <code>connection = cf.createConnection();</code> + </pre> + + <li>We create a JMS session. The session is created as non transacted and will auto acknowledge messages.</li> + <pre class="prettyprint"> + <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code> + </pre> + + <li>We create a JMS message producer on the session. This will be used to send the messages.</li> + <pre class="prettyprint"> + <code>MessageProducer producer = session.createProducer(queue);</code> + </pre> + + <li>We create a JMS text message that we are going to send.</li> + <pre class="prettyprint"> + <code>TextMessage message = session.createTextMessage("This is a scheduled message message which will be delivered in 5 sec.");</code> + </pre> + + <li>We schedule the delivery time to be 5 sec later.</li> + <pre class="prettyprint"> + <code> + long time = System.currentTimeMillis(); + time += 5000; + message.setLongProperty(MessageImpl.HDR_SCHEDULED_DELIVERY_TIME.toString(), time); + </code> + </pre> + + <li>We send message to the queue</li> + <pre class="prettyprint"> + <code>messageProducer.send(message);</code> + </pre> + + <li>We create a JMS Message Consumer to receive the message.</li> + <pre class="prettyprint"> + <code>MessageConsumer messageConsumer = session.createConsumer(queue);</code> + </pre> + + <li>We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started</li> + <pre class="prettyprint"> + <code>connection.start();</code> + </pre> + + <li>We use a blocking receive() to consume the message and see when the message arrives.</li> + <pre class="prettyprint"> + <code>TextMessage messageReceived = (TextMessage) messageConsumer.receive();</code> + </pre> + + <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> + + <pre class="prettyprint"> + <code>finally + { + if (initialContext != null) + { + initialContext.close(); + } + if (connection != null) + { + connection.close(); + } + }</code> + </pre> + + </ol> + + <h2>More information</h2> + + <ul> + <li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#scheduled-messages">Scheduled Messages chapter</a></li> + </ul> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/scheduled-message/src/main/java/org/apache/activemq/artemis/jms/example/ScheduledMessageExample.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/scheduled-message/src/main/java/org/apache/activemq/artemis/jms/example/ScheduledMessageExample.java b/examples/features/standard/scheduled-message/src/main/java/org/apache/activemq/artemis/jms/example/ScheduledMessageExample.java new file mode 100644 index 0000000..ba86949 --- /dev/null +++ b/examples/features/standard/scheduled-message/src/main/java/org/apache/activemq/artemis/jms/example/ScheduledMessageExample.java @@ -0,0 +1,94 @@ +/* + * 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 java.text.SimpleDateFormat; +import java.util.Date; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.apache.activemq.artemis.api.core.Message; + +public class ScheduledMessageExample { + + 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 + 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 a Text Message + TextMessage message = session.createTextMessage("This is a scheduled message message which will be delivered in 5 sec."); + + // Step 8. Set the delivery time to be 5 sec later. + long time = System.currentTimeMillis(); + time += 5000; + message.setLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME.toString(), time); + + // Step 9. Send the Message + producer.send(message); + + System.out.println("Sent message: " + message.getText()); + SimpleDateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss"); + System.out.println("Time of send: " + formatter.format(new Date())); + + // Step 10. Create a JMS Message Consumer + MessageConsumer messageConsumer = session.createConsumer(queue); + + // Step 11. Start the Connection + connection.start(); + + // Step 12. Receive the message + TextMessage messageReceived = (TextMessage) messageConsumer.receive(); + + System.out.println("Received message: " + messageReceived.getText()); + System.out.println("Time of receive: " + formatter.format(new Date())); + } + finally { + // Step 13. 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/scheduled-message/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/scheduled-message/src/main/resources/jndi.properties b/examples/features/standard/scheduled-message/src/main/resources/jndi.properties new file mode 100644 index 0000000..93537c4 --- /dev/null +++ b/examples/features/standard/scheduled-message/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/security/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/pom.xml b/examples/features/standard/security/pom.xml new file mode 100644 index 0000000..13976db --- /dev/null +++ b/examples/features/standard/security/pom.xml @@ -0,0 +1,111 @@ +<?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>security</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Security 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> + </configuration> + </execution> + <execution> + <id>start</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <ignore>${noServer}</ignore> + <spawn>true</spawn> + <testURI>tcp://localhost:61616</testURI> + <testUser>bill</testUser> + <testPassword>activemq</testPassword> + <args> + <param>run</param> + </args> + </configuration> + </execution> + <execution> + <id>runClient</id> + <goals> + <goal>runClient</goal> + </goals> + <configuration> + <clientClass>org.apache.activemq.artemis.jms.example.SecurityExample</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>security</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/security/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/readme.html b/examples/features/standard/security/readme.html new file mode 100644 index 0000000..d25dd42 --- /dev/null +++ b/examples/features/standard/security/readme.html @@ -0,0 +1,326 @@ +<!-- +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 Security 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 Security 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 how to configure and use security using ActiveMQ Artemis.</p> + + <p>With security properly configured, ActiveMQ Artemis can restrict client access to its resources, including + connection creation, message sending/receiving, etc. This is done by configuring users and roles as well as permissions in + the configuration files. </p> + + <p>ActiveMQ Artemis supports wild-card security configuration. This feature makes security configuration very + flexible and enables fine-grained control over permissions in an efficient way.</p> + + <p>For a full description of how to configure security with ActiveMQ Artemis, please consult the user + manual.</p> + + <p>This example demonstrates how to configure users/roles, how to configure topics with proper permissions using wild-card + expressions, and how they take effects in a simple program. </p> + + <p>First we need to configure users with roles. Users and Roles are configured in <code>activemq-users.xml</code>. This example has four users + configured as below </p> + + <pre class="prettyprint"> + <code> + <user name="bill" password="activemq"> + <role name="user"/> + </user> + + <user name="andrew" password="activemq1"> + <role name="europe-user"/> + <role name="user"/> + </user> + + <user name="frank" password="activemq2"> + <role name="us-user"/> + <role name="news-user"/> + <role name="user"/> + </user> + + <user name="sam" password="activemq3"> + <role name="news-user"/> + <role name="user"/> + </user> + </code> + </pre> + + <p> + Each user has three properties available: user name, password, and roles it belongs to. It should be noted that + a user can belong to more than one role. In the above configuration, all users belong to role 'user'. User 'andrew' also + belongs to role 'europe-user', user 'frank' also belongs to 'us-user' and 'news-user' and user 'sam' also belongs to 'news-user'. + </p> + <p> + User name and password consists of a valid account that can be used to establish connections to a ActiveMQ Artemis server, while + roles are used in controlling the access privileges against ActiveMQ Artemis topics and queues. You can achieve this control by + configuring proper permissions in <code>broker.xml</code>, like the following + </p> + <pre class="prettyprint"><code> + <security-settings> + <!-- any user can have full control of generic topics --> + <security-setting match="jms.topic.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="user"/> + <permission type="consume" roles="user"/> + </security-setting> + + <security-setting match="jms.topic.news.europe.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="europe-user"/> + <permission type="consume" roles="news-user"/> + </security-setting> + + <security-setting match="jms.topic.news.us.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="us-user"/> + <permission type="consume" roles="news-user"/> + </security-setting> + </security-settings> + </code></pre> + + <p>Permissions can be defined on any group of queues, by using a wildcard. You can easily specify + wildcards to apply certain permissions to a set of matching queues and topics. In the above configuration + we have created four sets of permissions, each set matches against a special group of targets, indicated by wild-card match attributes.</p> + + <p>You can provide a very broad permission control as a default and then add more strict control + over specific addresses. By the above we define the following access rules:</p> + + <li>Only role 'us-user' can create/delete and pulish messages to topics whose names match wild-card pattern 'news.us.#'.</li> + <li>Only role 'europe-user' can create/delete and publish messages to topics whose names match wild-card pattern 'news.europe.#'.</li> + <li>Only role 'news-user' can subscribe messages to topics whose names match wild-card pattern 'news.us.#' and 'news.europe.#'.</li> + <li>For any other topics that don't match any of the above wild-card patterns, permissions are granted to users of role 'user'.</li> + + <p>To illustrate the effect of permissions, three topics are deployed. Topic 'genericTopic' matches 'jms.topic.#' wild-card, topic 'news.europe.europeTopic' matches + jms.topic.news.europe.#' wild-cards, and topic 'news.us.usTopic' matches 'jms.topic.news.us.#'.</p> + + <p>With ActiveMQ Artemis, the security manager is also configurable. You can use JAASSecurityManager or JBossASSecurityManager based on you need. Please + check out the activemq-beans.xml for how to do. In this example we just use the basic ActiveMQSecurityManagerImpl which reads users/roles/passwords from the xml + file <code>activemq-users.xml</code>. + + + <h2>Example step-by-step</h2> + <p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p> + + <ol> + <li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li> + <pre class="prettyprint"> + <code> + InitialContext initialContext = getContext(0); + </code> + </pre> + + <li>We perform lookup on the topics</li> + <pre class="prettyprint"> + <code> + Topic genericTopic = (Topic) initialContext.lookup("/topic/genericTopic"); + Topic europeTopic = (Topic) initialContext.lookup("/topic/europeTopic"); + Topic usTopic = (Topic) initialContext.lookup("/topic/usTopic"); + </code> + </pre> + + <li>We perform a lookup on the Connection Factory</li> + <pre class="prettyprint"> + <code> + ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory"); + </code> + </pre> + + <li>We try to create a JMS Connection without user/password. It will fail.</li> + <pre class="prettyprint"> + <code> + try + { + cf.createConnection(); + result = false; + } + catch (JMSSecurityException e) + { + System.out.println("Default user cannot get a connection. Details: " + e.getMessage()); + } + </code> + </pre> + + <li>Bill tries to make a connection using wrong password</li> + <pre class="prettyprint"> + <code> + billConnection = null; + try + { + billConnection = createConnection("bill", "activemq1", cf); + result = false; + } + catch (JMSException e) + { + System.out.println("User bill failed to connect. Details: " + e.getMessage()); + } + </code> + </pre> + + <li>Bill makes a good connection.</li> + <pre class="prettyprint"> + <code> + billConnection = createConnection("bill", "activemq", cf); + billConnection.start(); + </code> + </pre> + + <li>Andrew makes a good connection</li> + <pre class="prettyprint"> + <code> + andrewConnection = createConnection("andrew", "activemq1", cf); + andrewConnection.start(); + </code> + </pre> + + <li>Frank makes a good connection</li> + <pre class="prettyprint"> + <code> + frankConnection = createConnection("frank", "activemq2", cf); + frankConnection.start(); + </code> + </pre> + + <li>Sam makes a good connection</li> + <pre class="prettyprint"> + <code> + samConnection = createConnection("sam", "activemq3", cf); + samConnection.start(); + </code> + </pre> + + <li>We check every user can publish/subscribe genericTopics</li> + <pre class="prettyprint"> + <code> + checkUserSendAndReceive(genericTopic, billConnection, "bill"); + checkUserSendAndReceive(genericTopic, andrewConnection, "andrew"); + checkUserSendAndReceive(genericTopic, frankConnection, "frank"); + checkUserSendAndReceive(genericTopic, samConnection, "sam"); + </code> + </pre> + + <li>We check permissions on news.europe.europeTopic for bill: can't send and can't receive</li> + <pre class="prettyprint"> + <code> + checkUserNoSendNoReceive(europeTopic, billConnection, "bill", andrewConnection, frankConnection); + </code> + </pre> + + <li>We check permissions on news.europe.europeTopic for andrew: can send but can't receive</li> + <pre class="prettyprint"> + <code> + checkUserSendNoReceive(europeTopic, andrewConnection, "andrew", frankConnection); + </code> + </pre> + + <li>We check permissions on news.europe.europeTopic for frank: can't send but can receive</li> + <pre class="prettyprint"> + <code> + checkUserReceiveNoSend(europeTopic, frankConnection, "frank", andrewConnection); + </code> + </pre> + + <li>We check permissions on news.europe.europeTopic for sam: can't send but can receive</li> + <pre class="prettyprint"> + <code> + checkUserReceiveNoSend(europeTopic, samConnection, "sam", andrewConnection); + </code> + </pre> + + <li>We check permissions on news.us.usTopic for bill: can't send and can't receive</li> + <pre class="prettyprint"> + <code> + checkUserNoSendNoReceive(usTopic, billConnection, "bill"); + </code> + </pre> + + <li>We check permissions on news.us.usTopic for andrew: can't send and can't receive</li> + <pre class="prettyprint"> + <code> + checkUserNoSendNoReceive(usTopic, andrewConnection, "andrew"); + </code> + </pre> + + <li>We check permissions on news.us.usTopic for frank: can both send and receive</li> + <pre class="prettyprint"> + <code> + checkUserSendAndReceive(usTopic, frankConnection, "frank"); + </code> + </pre> + + <li>We check permissions on news.us.usTopic for sam: can't send but can receive</li> + <pre class="prettyprint"> + <code> + checkUserReceiveNoSend(usTopic, samConnection, "sam", frankConnection); + </code> + </pre> + + <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> + + <pre class="prettyprint"> + <code> + finally + { + if (billConnection != null) + { + billConnection.close(); + } + if (andrewConnection != null) + { + andrewConnection.close(); + } + if (frankConnection != null) + { + frankConnection.close(); + } + if (samConnection != null) + { + samConnection.close(); + } + + // Also the initialContext + if (initialContext != null) + { + initialContext.close(); + } + } + </code> + </pre> + </ol> + </body> +</html> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/security/src/main/java/org/apache/activemq/artemis/jms/example/SecurityExample.java ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/src/main/java/org/apache/activemq/artemis/jms/example/SecurityExample.java b/examples/features/standard/security/src/main/java/org/apache/activemq/artemis/jms/example/SecurityExample.java new file mode 100644 index 0000000..88fd1da --- /dev/null +++ b/examples/features/standard/security/src/main/java/org/apache/activemq/artemis/jms/example/SecurityExample.java @@ -0,0 +1,282 @@ +/* + * 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.JMSException; +import javax.jms.JMSSecurityException; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.naming.InitialContext; + +public class SecurityExample { + + public static void main(final String[] args) throws Exception { + boolean result = true; + Connection failConnection = null; + Connection billConnection = null; + Connection andrewConnection = null; + Connection frankConnection = null; + Connection samConnection = null; + + InitialContext initialContext = null; + try { + // /Step 1. Create an initial context to perform the JNDI lookup. + initialContext = new InitialContext(); + + // Step 2. perform lookup on the topics + Topic genericTopic = (Topic) initialContext.lookup("topic/genericTopic"); + Topic europeTopic = (Topic) initialContext.lookup("topic/europeTopic"); + Topic usTopic = (Topic) initialContext.lookup("topic/usTopic"); + + // Step 3. perform a lookup on the Connection Factory + ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + + // Step 4. Try to create a JMS Connection without user/password. It will fail. + try { + failConnection = cf.createConnection(); + result = false; + } + catch (JMSSecurityException e) { + System.out.println("Default user cannot get a connection. Details: " + e.getMessage()); + } + + // Step 5. bill tries to make a connection using wrong password + billConnection = null; + try { + billConnection = createConnection("bill", "activemq1", cf); + result = false; + } + catch (JMSException e) { + System.out.println("User bill failed to connect. Details: " + e.getMessage()); + } + + // Step 6. bill makes a good connection. + billConnection = createConnection("bill", "activemq", cf); + billConnection.start(); + + // Step 7. andrew makes a good connection. + andrewConnection = createConnection("andrew", "activemq1", cf); + andrewConnection.start(); + + // Step 8. frank makes a good connection. + frankConnection = createConnection("frank", "activemq2", cf); + frankConnection.start(); + + // Step 9. sam makes a good connection. + samConnection = createConnection("sam", "activemq3", cf); + samConnection.start(); + + // Step 10. Check every user can publish/subscribe genericTopics. + System.out.println("------------------------Checking permissions on " + genericTopic + "----------------"); + checkUserSendAndReceive(genericTopic, billConnection, "bill"); + checkUserSendAndReceive(genericTopic, andrewConnection, "andrew"); + checkUserSendAndReceive(genericTopic, frankConnection, "frank"); + checkUserSendAndReceive(genericTopic, samConnection, "sam"); + System.out.println("-------------------------------------------------------------------------------------"); + + System.out.println("------------------------Checking permissions on " + europeTopic + "----------------"); + + // Step 11. Check permissions on news.europe.europeTopic for bill: can't send and can't receive + checkUserNoSendNoReceive(europeTopic, billConnection, "bill"); + + // Step 12. Check permissions on news.europe.europeTopic for andrew: can send but can't receive + checkUserSendNoReceive(europeTopic, andrewConnection, "andrew", frankConnection); + + // Step 13. Check permissions on news.europe.europeTopic for frank: can't send but can receive + checkUserReceiveNoSend(europeTopic, frankConnection, "frank", andrewConnection); + + // Step 14. Check permissions on news.europe.europeTopic for sam: can't send but can receive + checkUserReceiveNoSend(europeTopic, samConnection, "sam", andrewConnection); + System.out.println("-------------------------------------------------------------------------------------"); + + System.out.println("------------------------Checking permissions on " + usTopic + "----------------"); + + // Step 15. Check permissions on news.us.usTopic for bill: can't send and can't receive + checkUserNoSendNoReceive(usTopic, billConnection, "bill"); + + // Step 16. Check permissions on news.us.usTopic for andrew: can't send and can't receive + checkUserNoSendNoReceive(usTopic, andrewConnection, "andrew"); + + // Step 17. Check permissions on news.us.usTopic for frank: can both send and receive + checkUserSendAndReceive(usTopic, frankConnection, "frank"); + + // Step 18. Check permissions on news.us.usTopic for sam: can't send but can receive + checkUserReceiveNoSend(usTopic, samConnection, "sam", frankConnection); + System.out.println("-------------------------------------------------------------------------------------"); + } + finally { + // Step 19. Be sure to close our JMS resources! + if (failConnection != null) { + failConnection.close(); + } + if (billConnection != null) { + billConnection.close(); + } + if (andrewConnection != null) { + andrewConnection.close(); + } + if (frankConnection != null) { + frankConnection.close(); + } + if (samConnection != null) { + samConnection.close(); + } + + // Also the initialContext + if (initialContext != null) { + initialContext.close(); + } + } + } + + // Check the user can receive message but cannot send message. + private static void checkUserReceiveNoSend(final Topic topic, + final Connection connection, + final String user, + final Connection sendingConn) throws JMSException { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = session.createProducer(topic); + MessageConsumer consumer = session.createConsumer(topic); + TextMessage msg = session.createTextMessage("hello-world-1"); + + try { + producer.send(msg); + throw new IllegalStateException("Security setting is broken! User " + user + + " can send message [" + + msg.getText() + + "] to topic " + + topic); + } + catch (JMSException e) { + System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic); + } + + // Now send a good message + Session session1 = sendingConn.createSession(false, Session.AUTO_ACKNOWLEDGE); + producer = session1.createProducer(topic); + producer.send(msg); + + TextMessage receivedMsg = (TextMessage) consumer.receive(2000); + + if (receivedMsg != null) { + System.out.println("User " + user + " can receive message [" + receivedMsg.getText() + "] from topic " + topic); + } + else { + throw new IllegalStateException("Security setting is broken! User " + user + " cannot receive message from topic " + topic); + } + + session1.close(); + session.close(); + } + + // Check the user can send message but cannot receive message + private static void checkUserSendNoReceive(final Topic topic, + final Connection connection, + final String user, + final Connection receivingConn) throws JMSException { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = session.createProducer(topic); + try { + session.createConsumer(topic); + } + catch (JMSException e) { + System.out.println("User " + user + " cannot receive any message from topic " + topic); + } + + Session session1 = receivingConn.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer goodConsumer = session1.createConsumer(topic); + + TextMessage msg = session.createTextMessage("hello-world-2"); + producer.send(msg); + + TextMessage receivedMsg = (TextMessage) goodConsumer.receive(2000); + if (receivedMsg != null) { + System.out.println("User " + user + " can send message [" + receivedMsg.getText() + "] to topic " + topic); + } + else { + throw new IllegalStateException("Security setting is broken! User " + user + + " cannot send message [" + + msg.getText() + + "] to topic " + + topic); + } + + session.close(); + session1.close(); + } + + // Check the user has neither send nor receive permission on topic + private static void checkUserNoSendNoReceive(final Topic topic, + final Connection connection, + final String user) throws JMSException { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = session.createProducer(topic); + + try { + session.createConsumer(topic); + } + catch (JMSException e) { + System.out.println("User " + user + " cannot create consumer on topic " + topic); + } + + TextMessage msg = session.createTextMessage("hello-world-3"); + try { + producer.send(msg); + throw new IllegalStateException("Security setting is broken! User " + user + + " can send message [" + + msg.getText() + + "] to topic " + + topic); + } + catch (JMSException e) { + System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic); + } + + session.close(); + } + + // Check the user connection has both send and receive permissions on the topic + private static void checkUserSendAndReceive(final Topic topic, + final Connection connection, + final String user) throws JMSException { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + TextMessage msg = session.createTextMessage("hello-world-4"); + MessageProducer producer = session.createProducer(topic); + MessageConsumer consumer = session.createConsumer(topic); + producer.send(msg); + TextMessage receivedMsg = (TextMessage) consumer.receive(5000); + if (receivedMsg != null) { + System.out.println("User " + user + " can send message: [" + msg.getText() + "] to topic: " + topic); + System.out.println("User " + user + " can receive message: [" + msg.getText() + "] from topic: " + topic); + } + else { + throw new IllegalStateException("Error! User " + user + " cannot receive the message! "); + } + session.close(); + } + + private static Connection createConnection(final String username, + final String password, + final ConnectionFactory cf) throws JMSException { + return cf.createConnection(username, password); + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/security/src/main/resources/activemq/server0/artemis-roles.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/src/main/resources/activemq/server0/artemis-roles.properties b/examples/features/standard/security/src/main/resources/activemq/server0/artemis-roles.properties new file mode 100644 index 0000000..09b3f5d --- /dev/null +++ b/examples/features/standard/security/src/main/resources/activemq/server0/artemis-roles.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. +## --------------------------------------------------------------------------- +bill=user +andrew=europe-user,user +frank=us-user,news-user,user +sam=news-user,user \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/security/src/main/resources/activemq/server0/artemis-users.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/src/main/resources/activemq/server0/artemis-users.properties b/examples/features/standard/security/src/main/resources/activemq/server0/artemis-users.properties new file mode 100644 index 0000000..0a206c6 --- /dev/null +++ b/examples/features/standard/security/src/main/resources/activemq/server0/artemis-users.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. +## --------------------------------------------------------------------------- +bill=activemq +andrew=activemq1 +frank=activemq2 +sam=activemq3 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/security/src/main/resources/activemq/server0/broker.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/security/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000..6a8b82b --- /dev/null +++ b/examples/features/standard/security/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,81 @@ +<?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"> + <topic name="genericTopic"/> + + <topic name="news.europe.europeTopic"/> + + <topic name="news.us.usTopic"/> + </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> + + <!-- Acceptors --> + <acceptors> + <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor> + </acceptors> + + <!-- Other config --> + + <security-settings> + <!-- any user can have full control of generic topics --> + <security-setting match="jms.topic.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="user"/> + <permission type="consume" roles="user"/> + </security-setting> + + <security-setting match="jms.topic.news.europe.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="europe-user"/> + <permission type="consume" roles="news-user"/> + </security-setting> + + <security-setting match="jms.topic.news.us.#"> + <permission type="createDurableQueue" roles="user"/> + <permission type="deleteDurableQueue" roles="user"/> + <permission type="createNonDurableQueue" roles="user"/> + <permission type="deleteNonDurableQueue" roles="user"/> + <permission type="send" roles="us-user"/> + <permission type="consume" roles="news-user"/> + </security-setting> + </security-settings> + + </core> +</configuration> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/security/src/main/resources/jndi.properties ---------------------------------------------------------------------- diff --git a/examples/features/standard/security/src/main/resources/jndi.properties b/examples/features/standard/security/src/main/resources/jndi.properties new file mode 100644 index 0000000..0a3b640 --- /dev/null +++ b/examples/features/standard/security/src/main/resources/jndi.properties @@ -0,0 +1,22 @@ +# 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 +topic.topic/genericTopic=genericTopic +topic.topic/europeTopic=news.europe.europeTopic +topic.topic/usTopic=news.us.usTopic http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6b17d966/examples/features/standard/send-acknowledgements/pom.xml ---------------------------------------------------------------------- diff --git a/examples/features/standard/send-acknowledgements/pom.xml b/examples/features/standard/send-acknowledgements/pom.xml new file mode 100644 index 0000000..8295cdc --- /dev/null +++ b/examples/features/standard/send-acknowledgements/pom.xml @@ -0,0 +1,104 @@ +<?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>send-acknowledgements</artifactId> + <packaging>jar</packaging> + <name>ActiveMQ Artemis JMS Send Acknowledgements 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> + </execution> + <execution> + <id>start</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <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.SendAcknowledgementsExample</clientClass> + </configuration> + </execution> + <execution> + <id>stop</id> + <goals> + <goal>cli</goal> + </goals> + <configuration> + <args> + <param>stop</param> + </args> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.apache.activemq.examples.broker</groupId> + <artifactId>send-acknowledgements</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/send-acknowledgements/readme.html ---------------------------------------------------------------------- diff --git a/examples/features/standard/send-acknowledgements/readme.html b/examples/features/standard/send-acknowledgements/readme.html new file mode 100644 index 0000000..fcc37fc --- /dev/null +++ b/examples/features/standard/send-acknowledgements/readme.html @@ -0,0 +1,140 @@ +<!-- +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 Asynchronous Send Acknowledgements 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>Asynchronous Send Acknowledgements 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>Asynchronous Send Acknowledgements are an advanced feature of ActiveMQ Artemis which allow you to + receive acknowledgements that messages were successfully received at the server in a separate thread to the sending thread<p/> + <p>In this example we create a normal JMS session, then set a SendAcknowledgementHandler on the JMS + session's underlying core session. We send many messages to the server without blocking and asynchronously + receive send acknowledgements via the SendAcknowledgementHandler. + + <p>For more information on Asynchronous Send Acknowledgements please see the user manual</p> + <h2>Example step-by-step</h2> + <p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p> + + <ol> + <li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li> + <pre class="prettyprint"> + <code>InitialContext initialContext = getContext();</code> + </pre> + + <li>We look-up the JMS queue object from JNDI</li> + <pre class="prettyprint"> + <code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code> + </pre> + + <li>We look-up the JMS connection factory object from JNDI</li> + <pre class="prettyprint"> + <code>ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");</code> + </pre> + + <li>We create a JMS connection</li> + <pre class="prettyprint"> + <code>connection = cf.createConnection();</code> + </pre> + + <li>Define a SendAcknowledgementHandler which will receive asynchronous acknowledgements</li> + <pre class="prettyprint"> + <code> + class MySendAcknowledgementsHandler implements SendAcknowledgementHandler + { + int count = 0; + + public void sendAcknowledged(final Message message) + { + System.out.println("Received send acknowledgement for message " + count++); + } + } + </code> + </pre> + + <li>Create a JMS session</li> + <pre class="prettyprint"> + <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code> + </pre> + + <li>Set the handler on the underlying core session</li> + <pre class="prettyprint"> + <code> + ClientSession coreSession = ((ActiveMQSession)session).getCoreSession(); + + coreSession.setSendAcknowledgementHandler(new MySendAcknowledgementsHandler()); + + </code> + </pre> + + <li>Create a JMS Message Producer</li> + <pre class="prettyprint"> + <code> + MessageProducer producer = session.createProducer(queue); + + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + </code> + </pre> + + <li>Send 5000 messages, the handler will get called asynchronously some time later after the messages are sent.</li> + <pre class="prettyprint"> + <code> + final int numMessages = 5000; + + for (int i = 0; i < numMessages; i++) + { + javax.jms.Message jmsMessage = session.createMessage(); + + producer.send(jmsMessage); + + System.out.println("Sent message " + i); + } + </code> + </pre> + + + <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> + + <pre class="prettyprint"> + <code>finally + { + if (initialContext != null) + { + initialContext.close(); + } + if (connection != null) + { + connection.close(); + } + }</code> + </pre> + + + + </ol> + </body> +</html>