You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2012/11/12 01:15:56 UTC

svn commit: r1408161 [4/4] - in /activemq/trunk: activemq-core/src/test/java/org/apache/activemq/transport/stomp/ activemq-core/src/test/resources/org/apache/activemq/transport/stomp/ activemq-stomp/ activemq-stomp/src/test/ activemq-stomp/src/test/jav...

Propchange: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTestSupport.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTestSupport.java?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTestSupport.java (added)
+++ activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTestSupport.java Mon Nov 12 00:15:50 2012
@@ -0,0 +1,285 @@
+/**
+ * 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.transport.stomp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.Socket;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.AutoFailTestSupport;
+import org.apache.activemq.broker.BrokerPlugin;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.TransportConnector;
+import org.apache.activemq.filter.DestinationMapEntry;
+import org.apache.activemq.security.AuthenticationUser;
+import org.apache.activemq.security.AuthorizationEntry;
+import org.apache.activemq.security.AuthorizationMap;
+import org.apache.activemq.security.AuthorizationPlugin;
+import org.apache.activemq.security.DefaultAuthorizationMap;
+import org.apache.activemq.security.SimpleAuthenticationPlugin;
+import org.apache.activemq.transport.stomp.util.ResourceLoadingSslContext;
+import org.apache.activemq.transport.stomp.util.XStreamBrokerContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+public class StompTestSupport {
+
+    protected final AutoFailTestSupport autoFailTestSupport = new AutoFailTestSupport() {};
+    protected BrokerService brokerService;
+    protected int port;
+    protected int sslPort;
+    protected int nioPort;
+    protected int nioSslPort;
+    protected String jmsUri = "vm://localhost";
+    protected StompConnection stompConnection = new StompConnection();
+    protected ActiveMQConnectionFactory cf;
+
+    @Rule public TestName name = new TestName();
+
+    public File basedir() throws IOException {
+        ProtectionDomain protectionDomain = getClass().getProtectionDomain();
+        return new File(new File(protectionDomain.getCodeSource().getLocation().getPath()), "../..").getCanonicalFile();
+    }
+
+    public static void main(String[] args) throws Exception {
+        final StompTestSupport s = new StompTestSupport();
+
+        s.sslPort = 5675;
+        s.port = 5676;
+        s.nioPort = 5677;
+        s.nioSslPort = 5678;
+
+        s.startBroker();
+        while(true) {
+            Thread.sleep(100000);
+        }
+    }
+
+    public String getName() {
+        return name.getMethodName();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        autoFailTestSupport.startAutoFailThread();
+        startBroker();
+        stompConnect();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        autoFailTestSupport.stopAutoFailThread();
+        try {
+            stompDisconnect();
+        } catch (Exception ex) {
+            // its okay if the stomp connection is already closed.
+        } finally {
+            stopBroker();
+        }
+    }
+
+    public void startBroker() throws Exception {
+
+        createBroker();
+
+        XStreamBrokerContext context = new XStreamBrokerContext();
+        brokerService.setBrokerContext(context);
+
+        applyBrokerPolicies();
+        applyMemoryLimitPolicy();
+
+        // Setup SSL context...
+        File keyStore = new File(basedir(), "src/test/resources/server.keystore");
+        File trustStore = new File(basedir(), "src/test/resources/client.keystore");
+
+        final ResourceLoadingSslContext sslContext = new ResourceLoadingSslContext();
+        sslContext.setKeyStore(keyStore.getCanonicalPath());
+        sslContext.setKeyStorePassword("password");
+        sslContext.setTrustStore(trustStore.getCanonicalPath());
+        sslContext.setTrustStorePassword("password");
+        sslContext.afterPropertiesSet();
+        brokerService.setSslContext(sslContext);
+
+        ArrayList<BrokerPlugin> plugins = new ArrayList<BrokerPlugin>();
+
+        addStompConnector();
+        addOpenWireConnector();
+
+        cf = new ActiveMQConnectionFactory(jmsUri);
+
+        BrokerPlugin authenticationPlugin = configureAuthentication();
+        if (authenticationPlugin != null) {
+            plugins.add(configureAuthorization());
+        }
+
+        BrokerPlugin authorizationPlugin = configureAuthorization();
+        if (authorizationPlugin != null) {
+            plugins.add(configureAuthentication());
+        }
+
+        if (!plugins.isEmpty()) {
+            BrokerPlugin[] array = new BrokerPlugin[plugins.size()];
+            brokerService.setPlugins(plugins.toArray(array));
+        }
+
+        brokerService.start();
+        brokerService.waitUntilStarted();
+    }
+
+    protected void applyMemoryLimitPolicy() throws Exception {
+    }
+
+    protected void createBroker() throws Exception {
+        brokerService = new BrokerService();
+        brokerService.setPersistent(false);
+        brokerService.setAdvisorySupport(false);
+        brokerService.setSchedulerSupport(true);
+        brokerService.setPopulateJMSXUserID(true);
+    }
+
+    protected BrokerPlugin configureAuthentication() throws Exception {
+        List<AuthenticationUser> users = new ArrayList<AuthenticationUser>();
+        users.add(new AuthenticationUser("system", "manager", "users,admins"));
+        users.add(new AuthenticationUser("user", "password", "users"));
+        users.add(new AuthenticationUser("guest", "password", "guests"));
+        SimpleAuthenticationPlugin authenticationPlugin = new SimpleAuthenticationPlugin(users);
+
+        return authenticationPlugin;
+    }
+
+    protected BrokerPlugin configureAuthorization() throws Exception {
+
+        @SuppressWarnings("rawtypes")
+        List<DestinationMapEntry> authorizationEntries = new ArrayList<DestinationMapEntry>();
+
+        AuthorizationEntry entry = new AuthorizationEntry();
+        entry.setQueue(">");
+        entry.setRead("admins");
+        entry.setWrite("admins");
+        entry.setAdmin("admins");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setQueue("USERS.>");
+        entry.setRead("users");
+        entry.setWrite("users");
+        entry.setAdmin("users");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setQueue("GUEST.>");
+        entry.setRead("guests");
+        entry.setWrite("guests,users");
+        entry.setAdmin("guests,users");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setTopic(">");
+        entry.setRead("admins");
+        entry.setWrite("admins");
+        entry.setAdmin("admins");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setTopic("USERS.>");
+        entry.setRead("users");
+        entry.setWrite("users");
+        entry.setAdmin("users");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setTopic("GUEST.>");
+        entry.setRead("guests");
+        entry.setWrite("guests,users");
+        entry.setAdmin("guests,users");
+        authorizationEntries.add(entry);
+        entry = new AuthorizationEntry();
+        entry.setTopic("ActiveMQ.Advisory.>");
+        entry.setRead("guests,users");
+        entry.setWrite("guests,users");
+        entry.setAdmin("guests,users");
+        authorizationEntries.add(entry);
+
+        AuthorizationMap authorizationMap = new DefaultAuthorizationMap(authorizationEntries);
+        AuthorizationPlugin authorizationPlugin = new AuthorizationPlugin(authorizationMap);
+
+        return authorizationPlugin;
+    }
+
+    protected void applyBrokerPolicies() throws Exception {
+        // NOOP here
+    }
+
+    protected void addOpenWireConnector() throws Exception {
+    }
+
+    protected void addStompConnector() throws Exception {
+        TransportConnector connector = null;
+
+        // Subclasses can tailor this list to speed up the test startup / shutdown
+        connector = brokerService.addConnector("stomp+ssl://0.0.0.0:"+sslPort);
+        sslPort = connector.getConnectUri().getPort();
+        connector = brokerService.addConnector("stomp://0.0.0.0:"+port);
+        port = connector.getConnectUri().getPort();
+        connector = brokerService.addConnector("stomp+nio://0.0.0.0:"+nioPort);
+        nioPort = connector.getConnectUri().getPort();
+        connector = brokerService.addConnector("stomp+nio+ssl://0.0.0.0:"+nioSslPort);
+        nioSslPort = connector.getConnectUri().getPort();
+    }
+
+    public void stopBroker() throws Exception {
+        if (brokerService != null) {
+            brokerService.stop();
+            brokerService.waitUntilStopped();
+            brokerService = null;
+        }
+    }
+
+    protected StompConnection stompConnect() throws Exception {
+        if (stompConnection == null) {
+            stompConnection = new StompConnection();
+        }
+        stompConnection.open(createSocket());
+        return stompConnection;
+    }
+
+    protected StompConnection stompConnect(StompConnection connection) throws Exception {
+        connection.open(createSocket());
+        return stompConnection;
+    }
+
+    protected Socket createSocket() throws IOException {
+        return new Socket("127.0.0.1", this.port);
+    }
+
+    protected String getQueueName() {
+        return getClass().getName() + "." + name.getMethodName();
+    }
+
+    protected String getTopicName() {
+        return getClass().getName() + "." + name.getMethodName();
+    }
+
+    protected void stompDisconnect() throws IOException {
+        if (stompConnection != null) {
+            stompConnection.close();
+            stompConnection = null;
+        }
+    }
+}

Propchange: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompTestSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompVirtualTopicTest.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompVirtualTopicTest.java?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompVirtualTopicTest.java (added)
+++ activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompVirtualTopicTest.java Mon Nov 12 00:15:50 2012
@@ -0,0 +1,257 @@
+/**
+ * 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.transport.stomp;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+import javax.management.ObjectName;
+
+import junit.framework.Assert;
+
+import org.apache.activemq.broker.BrokerFactory;
+import org.apache.activemq.broker.jmx.QueueViewMBean;
+import org.apache.activemq.broker.region.policy.FilePendingQueueMessageStoragePolicy;
+import org.apache.activemq.broker.region.policy.PolicyEntry;
+import org.apache.activemq.broker.region.policy.PolicyMap;
+import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
+import org.apache.activemq.usage.SystemUsage;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StompVirtualTopicTest extends StompTestSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(StompVirtualTopicTest.class);
+    private static final int NUM_MSGS = 100000;
+
+    private String failMsg = null;
+
+    @Override
+    protected void createBroker() throws Exception {
+        brokerService = BrokerFactory.createBroker(new URI("broker://()/localhost"));
+        brokerService.setUseJmx(true);
+        brokerService.setDeleteAllMessagesOnStartup(true);
+
+        File testDataDir = new File("target/activemq-data/StompVirtualTopicTest");
+        brokerService.setDataDirectoryFile(testDataDir);
+        KahaDBPersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
+        persistenceAdapter.setDirectory(new File(testDataDir, "kahadb"));
+        brokerService.setPersistenceAdapter(persistenceAdapter);
+    }
+
+    @Override
+    protected void applyMemoryLimitPolicy() throws Exception {
+        final SystemUsage memoryManager = new SystemUsage();
+        memoryManager.getMemoryUsage().setLimit(5818230784L);
+        memoryManager.getStoreUsage().setLimit(6442450944L);
+        memoryManager.getTempUsage().setLimit(3221225472L);
+        brokerService.setSystemUsage(memoryManager);
+
+        final List<PolicyEntry> policyEntries = new ArrayList<PolicyEntry>();
+        final PolicyEntry entry = new PolicyEntry();
+        entry.setQueue(">");
+        entry.setProducerFlowControl(false);
+        entry.setMemoryLimit(10485760);
+        entry.setPendingQueuePolicy(new FilePendingQueueMessageStoragePolicy());
+        policyEntries.add(entry);
+
+        final PolicyMap policyMap = new PolicyMap();
+        policyMap.setPolicyEntries(policyEntries);
+        brokerService.setDestinationPolicy(policyMap);
+    }
+
+    @Test
+    public void testStompOnVirtualTopics() throws Exception {
+        LOG.info("Running Stomp Producer");
+
+        StompConsumer consumerWorker = new StompConsumer(this);
+        Thread consumer = new Thread(consumerWorker);
+
+        consumer.start();
+        consumerWorker.awaitStartCompleted();
+        Thread.sleep(500);
+
+        stompConnection.sendFrame("CONNECT\n" + "login:system\n" + "passcode:manager\n\n" + Stomp.NULL);
+        StompFrame frame = stompConnection.receive();
+        assertTrue(frame.toString().startsWith("CONNECTED"));
+
+        for (int i=0; i<NUM_MSGS-1; i++) {
+            stompConnection.send("/topic/VirtualTopic.FOO", "Hello World {" + (i + 1) + "}");
+        }
+
+        LOG.info("Sending last packet with receipt header");
+        HashMap<String, Object> headers = new HashMap<String, Object>();
+        headers.put("receipt", "1234");
+        stompConnection.appendHeaders(headers);
+        String msg = "SEND\n" + "destination:/topic/VirtualTopic.FOO\n" +
+                     "receipt: msg-1\n" + "\n\n" + "Hello World {" + (NUM_MSGS-1) + "}" + Stomp.NULL;
+        stompConnection.sendFrame(msg);
+
+        msg = stompConnection.receiveFrame();
+        assertTrue(msg.contains("RECEIPT"));
+
+        // Does the sleep resolve the problem?
+        try {
+            Thread.sleep(6000);
+        } catch (java.lang.InterruptedException e) {
+            LOG.error(e.getMessage());
+        }
+        stompConnection.disconnect();
+        Thread.sleep(2000);
+        stompConnection.close();
+        LOG.info("Stomp Producer finished. Waiting for consumer to join.");
+
+        //wait for consumer to shut down
+        consumer.join();
+        LOG.info("Test finished.");
+
+        // check if consumer set failMsg, then let the test fail.
+        if (null != failMsg) {
+            LOG.error(failMsg);
+            Assert.fail(failMsg);
+        }
+    }
+
+    /*
+     * Allow Consumer thread to indicate the test has failed.
+     * JUnits Assert.fail() does not work in threads spawned.
+     */
+    protected void setFail(String msg) {
+        this.failMsg = msg;
+    }
+
+    class StompConsumer implements Runnable {
+        final Logger log = LoggerFactory.getLogger(StompConsumer.class);
+        private StompVirtualTopicTest parent = null;
+        private final CountDownLatch latch = new CountDownLatch(1);
+        private final HashSet<String> received = new HashSet<String>();
+        private final HashSet<String> dups = new HashSet<String>();
+
+        public StompConsumer(StompVirtualTopicTest ref) {
+            parent = ref;
+        }
+
+        public void awaitStartCompleted() {
+            try {
+                this.latch.await();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        @Override
+        public void run() {
+
+            LOG.info("Running Stomp Consumer");
+
+            StompConnection stompConnection = new StompConnection();
+            int counter = 0;
+
+            try {
+                stompConnection.open("localhost", StompVirtualTopicTest.this.port);
+                stompConnection.sendFrame("CONNECT\n" + "login:system\n" + "passcode:manager\n\n" + Stomp.NULL);
+                StompFrame frame = stompConnection.receive();
+                assertTrue(frame.toString().startsWith("CONNECTED"));
+                stompConnection.subscribe("/queue/Consumer.A.VirtualTopic.FOO", "auto");
+
+                Thread.sleep(2000);
+                latch.countDown();
+
+                for (counter=0; counter<StompVirtualTopicTest.NUM_MSGS; counter++) {
+                    frame = stompConnection.receive(15000);
+                    log.trace("Received msg with content: " + frame.getBody());
+                    if(!received.add(frame.getBody())) {
+                        dups.add(frame.getBody());
+                    }
+                }
+
+                // another receive should not return any more msgs
+                try {
+                    frame = stompConnection.receive(3000);
+                    Assert.assertNull(frame);
+                } catch (Exception e) {
+                    LOG.info("Correctly received " + e + " while trying to consume an additional msg." +
+                            " This is expected as the queue should be empty now.");
+                }
+
+                // in addition check QueueSize using JMX
+                long queueSize = reportQueueStatistics();
+
+                if (queueSize != 0) {
+                    parent.setFail("QueueSize not 0 after test has finished.");
+                }
+
+                log.debug("Stomp Consumer Received " + counter + " of " + StompVirtualTopicTest.NUM_MSGS +
+                          " messages. Check QueueSize in JMX and try to browse the queue.");
+
+                if(!dups.isEmpty()) {
+                    for(String msg : dups) {
+                        LOG.debug("Received duplicate message: " + msg);
+                    }
+
+                    parent.setFail("Received " + StompVirtualTopicTest.NUM_MSGS +
+                                   " messages but " + dups.size() + " were dups.");
+                }
+
+            } catch (Exception ex) {
+                log.error(ex.getMessage() + " after consuming " + counter + " msgs.");
+
+                try {
+                    reportQueueStatistics();
+                } catch (Exception e) {
+                }
+
+                parent.setFail("Stomp Consumer received " + counter + " of " + StompVirtualTopicTest.NUM_MSGS +
+                               " messages. Check QueueSize in JMX and try to browse the queue.");
+
+            } finally {
+                try {
+                    stompConnection.disconnect();
+                    Thread.sleep(2000);
+                    stompConnection.close();
+                } catch (Exception e) {
+                    log.error("unexpected exception on sleep", e);
+                }
+            }
+
+            log.info("Test Finished.");
+        }
+
+        private long reportQueueStatistics() throws Exception {
+
+            ObjectName queueViewMBeanName = new ObjectName("org.apache.activemq:Type=Queue" +
+                                                           ",Destination=Consumer.A.VirtualTopic.FOO" +
+                                                           ",BrokerName=localhost");
+            QueueViewMBean queue = (QueueViewMBean)
+                brokerService.getManagementContext().newProxyInstance(queueViewMBeanName, QueueViewMBean.class, true);
+
+            LOG.info("Consumer.A.VirtualTopic.FOO Inflight: " + queue.getInFlightCount() +
+                     ", enqueueCount: " + queue.getEnqueueCount() + ", dequeueCount: " +
+                     queue.getDequeueCount() + ", dispatchCount: " + queue.getDispatchCount());
+
+            return queue.getQueueSize();
+        }
+    }
+}
+

Propchange: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompVirtualTopicTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/ResourceLoadingSslContext.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/ResourceLoadingSslContext.java?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/ResourceLoadingSslContext.java (added)
+++ activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/ResourceLoadingSslContext.java Mon Nov 12 00:15:50 2012
@@ -0,0 +1,223 @@
+/**
+ * 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.transport.stomp.util;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.annotation.PostConstruct;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.activemq.broker.SslContext;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.util.ResourceUtils;
+
+/**
+ * Extends the SslContext so that it's easier to configure from spring.
+ */
+public class ResourceLoadingSslContext extends SslContext {
+
+    private String keyStoreType="jks";
+    private String trustStoreType="jks";
+
+    private String secureRandomAlgorithm="SHA1PRNG";
+    private String keyStoreAlgorithm=KeyManagerFactory.getDefaultAlgorithm();
+    private String trustStoreAlgorithm=TrustManagerFactory.getDefaultAlgorithm();
+
+    private String keyStore;
+    private String trustStore;
+
+    private String keyStoreKeyPassword;
+    private String keyStorePassword;
+    private String trustStorePassword;
+
+    /**
+     *
+     * @throws Exception
+     * @org.apache.xbean.InitMethod
+     */
+    @PostConstruct
+    public void afterPropertiesSet() throws Exception {
+        keyManagers.addAll(createKeyManagers());
+        trustManagers.addAll(createTrustManagers());
+        if( secureRandom == null ) {
+            secureRandom = createSecureRandom();
+        }
+    }
+
+    private SecureRandom createSecureRandom() throws NoSuchAlgorithmException {
+        return SecureRandom.getInstance(secureRandomAlgorithm);
+    }
+
+    private Collection<TrustManager> createTrustManagers() throws Exception {
+        KeyStore ks = createTrustManagerKeyStore();
+        if( ks ==null ) {
+            return new ArrayList<TrustManager>(0);
+        }
+
+        TrustManagerFactory tmf  = TrustManagerFactory.getInstance(trustStoreAlgorithm);
+        tmf.init(ks);
+        return Arrays.asList(tmf.getTrustManagers());
+    }
+
+    private Collection<KeyManager> createKeyManagers() throws Exception {
+        KeyStore ks = createKeyManagerKeyStore();
+        if( ks ==null ) {
+            return new ArrayList<KeyManager>(0);
+        }
+
+        KeyManagerFactory tmf  = KeyManagerFactory.getInstance(keyStoreAlgorithm);
+        tmf.init(ks, keyStoreKeyPassword == null ? (keyStorePassword==null? null : keyStorePassword.toCharArray()) : keyStoreKeyPassword.toCharArray());
+        return Arrays.asList(tmf.getKeyManagers());
+    }
+
+    private KeyStore createTrustManagerKeyStore() throws Exception {
+        if( trustStore ==null ) {
+            return null;
+        }
+
+        KeyStore ks = KeyStore.getInstance(trustStoreType);
+        InputStream is=resourceFromString(trustStore).getInputStream();
+        try {
+            ks.load(is, trustStorePassword==null? null : trustStorePassword.toCharArray());
+        } finally {
+            is.close();
+        }
+        return ks;
+    }
+
+    private KeyStore createKeyManagerKeyStore() throws Exception {
+        if( keyStore ==null ) {
+            return null;
+        }
+
+        KeyStore ks = KeyStore.getInstance(keyStoreType);
+        InputStream is=resourceFromString(keyStore).getInputStream();
+        try {
+            ks.load(is, keyStorePassword==null? null : keyStorePassword.toCharArray());
+        } finally {
+            is.close();
+        }
+        return ks;
+    }
+
+    public String getTrustStoreType() {
+        return trustStoreType;
+    }
+
+    public String getKeyStoreType() {
+        return keyStoreType;
+    }
+
+    public String getKeyStore() {
+        return keyStore;
+    }
+
+    public void setKeyStore(String keyStore) throws MalformedURLException {
+        this.keyStore = keyStore;
+    }
+
+    public String getTrustStore() {
+        return trustStore;
+    }
+
+    public void setTrustStore(String trustStore) throws MalformedURLException {
+        this.trustStore = trustStore;
+    }
+
+    public String getKeyStoreAlgorithm() {
+        return keyStoreAlgorithm;
+    }
+
+    public void setKeyStoreAlgorithm(String keyAlgorithm) {
+        this.keyStoreAlgorithm = keyAlgorithm;
+    }
+
+    public String getTrustStoreAlgorithm() {
+        return trustStoreAlgorithm;
+    }
+
+    public void setTrustStoreAlgorithm(String trustAlgorithm) {
+        this.trustStoreAlgorithm = trustAlgorithm;
+    }
+
+    public String getKeyStoreKeyPassword() {
+        return keyStoreKeyPassword;
+    }
+
+    public void setKeyStoreKeyPassword(String keyPassword) {
+        this.keyStoreKeyPassword = keyPassword;
+    }
+
+    public String getKeyStorePassword() {
+        return keyStorePassword;
+    }
+
+    public void setKeyStorePassword(String keyPassword) {
+        this.keyStorePassword = keyPassword;
+    }
+
+    public String getTrustStorePassword() {
+        return trustStorePassword;
+    }
+
+    public void setTrustStorePassword(String trustPassword) {
+        this.trustStorePassword = trustPassword;
+    }
+
+    public void setKeyStoreType(String keyType) {
+        this.keyStoreType = keyType;
+    }
+
+    public void setTrustStoreType(String trustType) {
+        this.trustStoreType = trustType;
+    }
+
+    public String getSecureRandomAlgorithm() {
+        return secureRandomAlgorithm;
+    }
+
+    public void setSecureRandomAlgorithm(String secureRandomAlgorithm) {
+        this.secureRandomAlgorithm = secureRandomAlgorithm;
+    }
+
+    public static Resource resourceFromString(String uri) throws MalformedURLException {
+        Resource resource;
+        File file = new File(uri);
+        if (file.exists()) {
+            resource = new FileSystemResource(uri);
+        } else if (ResourceUtils.isUrl(uri)) {
+            resource = new UrlResource(uri);
+        } else {
+            resource = new ClassPathResource(uri);
+        }
+        return resource;
+    }
+}

Propchange: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/ResourceLoadingSslContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java (added)
+++ activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java Mon Nov 12 00:15:50 2012
@@ -0,0 +1,55 @@
+/**
+ * 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.transport.stomp.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.activemq.broker.BrokerContext;
+import org.apache.activemq.transport.stomp.SamplePojo;
+
+import com.thoughtworks.xstream.XStream;
+
+public class XStreamBrokerContext implements BrokerContext {
+
+    private final Map<String, XStream> beansMap = new HashMap<String, XStream>();
+
+    public XStreamBrokerContext() {
+
+        XStream stream = new XStream();
+        stream.processAnnotations(SamplePojo.class);
+
+        beansMap.put("xstream", stream);
+    }
+
+    @Override
+    public Object getBean(String name) {
+        return this.beansMap.get(name);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Map getBeansOfType(Class type) {
+
+        if (type.equals(XStream.class)) {
+            return this.beansMap;
+        }
+
+        return null;
+    }
+
+}

Propchange: activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/util/XStreamBrokerContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/resources/client.keystore
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/client.keystore?rev=1408161&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/trunk/activemq-stomp/src/test/resources/client.keystore
------------------------------------------------------------------------------
    svn:executable = *

Propchange: activemq/trunk/activemq-stomp/src/test/resources/client.keystore
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/trunk/activemq-stomp/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/log4j.properties?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/resources/log4j.properties (added)
+++ activemq/trunk/activemq-stomp/src/test/resources/log4j.properties Mon Nov 12 00:15:50 2012
@@ -0,0 +1,42 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+#
+# The logging properties used during tests..
+#
+log4j.rootLogger=INFO, out, stdout
+
+#log4j.logger.org.apache.activemq.broker.scheduler=DEBUG
+#log4j.logger.org.apache.activemq.network.DemandForwardingBridgeSupport=DEBUG
+#log4j.logger.org.apache.activemq.transport.failover=TRACE
+#log4j.logger.org.apache.activemq.store.jdbc=TRACE
+#log4j.logger.org.apache.activemq.broker.region.cursors.AbstractStoreCursor=DEBUG
+#log4j.logger.org.apache.activemq.store.jdbc.JDBCMessageStore=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
+#log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %-10.10X{activemq.broker} %-20.20X{activemq.connector} %-10.10X{activemq.destination} - %m%n
+
+# File appender
+log4j.appender.out=org.apache.log4j.FileAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %-10.10X{activemq.broker} %-20.20X{activemq.connector} %-10.10X{activemq.destination} - %m%n
+log4j.appender.out.file=target/activemq-test.log
+log4j.appender.out.append=true

Propchange: activemq/trunk/activemq-stomp/src/test/resources/log4j.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/trunk/activemq-stomp/src/test/resources/log4j.properties
------------------------------------------------------------------------------
    svn:executable = *

Added: activemq/trunk/activemq-stomp/src/test/resources/login.config
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/login.config?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/resources/login.config (added)
+++ activemq/trunk/activemq-stomp/src/test/resources/login.config Mon Nov 12 00:15:50 2012
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+activemq-domain {
+    org.apache.activemq.jaas.PropertiesLoginModule required
+        debug=true
+        org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+        org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+};
+
+activemq-guest-domain {
+    org.apache.activemq.jaas.PropertiesLoginModule sufficient
+        debug=true
+        org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+        org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+    org.apache.activemq.jaas.GuestLoginModule sufficient
+       debug=true
+       org.apache.activemq.jaas.guest.user="guest"
+       org.apache.activemq.jaas.guest.group="guests";
+};
+
+activemq-guest-when-no-creds-only-domain {
+    org.apache.activemq.jaas.GuestLoginModule sufficient
+       debug=true
+       credentialsInvalidate=true
+       org.apache.activemq.jaas.guest.user="guest"
+       org.apache.activemq.jaas.guest.group="guests";
+
+    org.apache.activemq.jaas.PropertiesLoginModule requisite
+        debug=true
+        org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+        org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+};
+
+cert-login {
+    org.apache.activemq.jaas.TextFileCertificateLoginModule required
+        debug=true
+        org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users.properties"
+        org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+
+};
+
+broker1 {
+    org.apache.activemq.jaas.TextFileCertificateLoginModule required
+        debug=true
+        org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users1.properties"
+        org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+};
+
+broker2 {
+    org.apache.activemq.jaas.TextFileCertificateLoginModule required
+        debug=true
+        org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users2.properties"
+        org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+};
\ No newline at end of file

Propchange: activemq/trunk/activemq-stomp/src/test/resources/login.config
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/groups.properties
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/groups.properties?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/groups.properties (added)
+++ activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/groups.properties Mon Nov 12 00:15:50 2012
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+admins=system,sslclient,client,broker1,broker2
+tempDestinationAdmins=system,user,sslclient,client,broker1,broker2
+users=system,user,sslclient,client,broker1,broker2
+guests=guest

Propchange: activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/groups.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/users.properties
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/users.properties?rev=1408161&view=auto
==============================================================================
--- activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/users.properties (added)
+++ activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/users.properties Mon Nov 12 00:15:50 2012
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+system=manager
+user=password
+guest=password
+sslclient=CN=localhost, OU=activemq.org, O=activemq.org, L=LA, ST=CA, C=US
\ No newline at end of file

Propchange: activemq/trunk/activemq-stomp/src/test/resources/org/apache/activemq/security/users.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/trunk/activemq-stomp/src/test/resources/server.keystore
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-stomp/src/test/resources/server.keystore?rev=1408161&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/trunk/activemq-stomp/src/test/resources/server.keystore
------------------------------------------------------------------------------
    svn:executable = *

Propchange: activemq/trunk/activemq-stomp/src/test/resources/server.keystore
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream