View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact tma@netspace.net.au. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2003-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: ExpirationTest.java,v 1.3 2004/02/03 07:33:32 tanderson Exp $ 44 */ 45 package org.exolab.jmscts.test.producer.ttl; 46 47 import java.util.HashSet; 48 import java.util.Iterator; 49 import java.util.List; 50 51 import javax.jms.Message; 52 import javax.jms.Session; 53 54 import org.apache.log4j.Category; 55 56 import junit.framework.Test; 57 58 import org.exolab.jmscts.core.AbstractSendReceiveTestCase; 59 import org.exolab.jmscts.core.MessageReceiver; 60 import org.exolab.jmscts.core.MessageSender; 61 import org.exolab.jmscts.core.MessagingBehaviour; 62 import org.exolab.jmscts.core.TestContext; 63 import org.exolab.jmscts.core.TestContextHelper; 64 import org.exolab.jmscts.core.TestCreator; 65 import org.exolab.jmscts.core.TestProperties; 66 67 68 /*** 69 * This class tests message expiration 70 * 71 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 72 * @version $Revision: 1.3 $ 73 */ 74 public class ExpirationTest extends AbstractSendReceiveTestCase { 75 76 /*** 77 * The default destination 78 */ 79 private static final String DESTINATION = "ExpirationTest"; 80 81 /*** 82 * The logger 83 */ 84 private static final Category log = Category.getInstance( 85 ExpirationTest.class); 86 87 /*** 88 * The time in milliseconds to wait for the JMS provider to collect expired 89 * This can be set for providers which collect expired messages 90 * periodically, rather than at the moment they expire, and is a 91 * workaround for section 3.9 of the specification which states: 92 * "Clients should not receive messages which have expired, however JMS 93 * does not guarantee that this will not happen." 94 */ 95 private static final long EXPIRATION_INTERVAL = 96 TestProperties.getLong(ExpirationTest.class, "expirationInterval", 0); 97 98 99 /*** 100 * Construct a new <code>ExpirationTest</code> 101 * 102 * @param name the name of test case 103 */ 104 public ExpirationTest(String name) { 105 super(name); 106 } 107 108 /*** 109 * Sets up the test suite 110 * 111 * @return an instance of this class that may be run by 112 * {@link org.exolab.jmscts.core.JMSTestRunner} 113 */ 114 public static Test suite() { 115 return TestCreator.createSendReceiveTest(ExpirationTest.class); 116 } 117 118 /*** 119 * Returns the list of destination names used by this test case. These 120 * are used to pre-administer destinations prior to running the test case. 121 * 122 * @return the list of destinations used by this test case 123 */ 124 public String[] getDestinations() { 125 return new String[] {DESTINATION}; 126 } 127 128 /*** 129 * Verifies that messages expire. 130 * <p/> 131 * It sends two groups of messages - one group which expires after 132 * 1 second, and another which don't expire, and verifies that after 133 * the first group should have expired, only the non-expiring group 134 * can be received. 135 * <p/> 136 * If the JMS provider doesn't support immediate expiration of messages, 137 * the 138 * <em> 139 * org.exolab.jmscts.test.producer.ttl.ExpirationTest.expirationInterval 140 * </em> 141 * property should be configured in <em>jmscts.properties</em> to delay 142 * the test until the expired messages are collected. 143 * 144 * @jmscts.requirement message.expiration.zero 145 * @jmscts.requirement message.expiration.expired 146 * @jmscts.message TextMessage 147 * @throws Exception for any error 148 */ 149 public void testExpiration() throws Exception { 150 final long timeToLive = 1000; // i.e, 1 second 151 final int messages = 10; // no. of messages to send 152 final int receivers = 1; // no. of receivers. 153 checkExpiration(timeToLive, messages, receivers); 154 } 155 156 /*** 157 * Verifies that a single message expires. 158 * <p/> 159 * It sends two messages - one which expires after 1 second, and another 160 * which doesn't expire, and verifies that after the first should have 161 * expired, only the non-expiring message can be received. 162 * <p/> 163 * If the JMS provider doesn't support immediate expiration of messages, 164 * the 165 * <em> 166 * org.exolab.jmscts.test.producer.ttl.ExpirationTest.expirationInterval 167 * </em> 168 * property should be configured in <em>jmscts.properties</em> to delay 169 * the test until the expired messages are collected. 170 * 171 * @jmscts.requirement message.expiration.zero 172 * @jmscts.requirement message.expiration.expired 173 * @jmscts.message TextMessage 174 * @throws Exception for any error 175 */ 176 public void testSingleMessageExpiration() throws Exception { 177 final long timeToLive = 1000; // i.e, 1 second 178 final int messages = 1; // no. of messages to send 179 final int receivers = 1; // no. of receivers. 180 checkExpiration(timeToLive, messages, receivers); 181 } 182 183 /*** 184 * Verifies that messages to topics expire, when there is more than 185 * one subscriber. 186 * <p/> 187 * It sends two groups of messages - one group which expires after 188 * 1 second, and another which don't expire, and verifies that after 189 * the first group should have expired, only the non-expiring group 190 * can be received. 191 * <p/> 192 * If the JMS provider doesn't support immediate expiration of messages, 193 * the 194 * <em> 195 * org.exolab.jmscts.test.producer.ttl.ExpirationTest.expirationInterval 196 * </em> 197 * property should be configured in <em>jmscts.properties</em> to delay 198 * the test until the expired messages are collected. 199 * 200 * @jmscts.requirement message.expiration.zero 201 * @jmscts.requirement message.expiration.expired 202 * @jmscts.factory TopicConnectionFactory 203 * @jmscts.factory XATopicConnectionFactory 204 * @jmscts.message ObjectMessage 205 * @throws Exception for any error 206 */ 207 public void testExpiration2Subscribers() throws Exception { 208 final long timeToLive = 1000; // i.e, 1 second 209 final int messages = 10; // no. of messages to send 210 final int subscribers = 2; // no. of subscribers. 211 checkExpiration(timeToLive, messages, subscribers); 212 } 213 214 /*** 215 * Verifies that messages to topics expire, when one subscriber is 216 * durable, and the other non-durable. 217 * <p/> 218 * It sends two groups of messages - one group which expires after 219 * 1 second, and another which don't expire, and verifies that after 220 * the first group should have expired, only the non-expiring group 221 * can be received. 222 * <p/> 223 * If the JMS provider doesn't support immediate expiration of messages, 224 * the 225 * <em> 226 * org.exolab.jmscts.test.producer.ttl.ExpirationTest.expirationInterval 227 * </em> 228 * property should be configured in <em>jmscts.properties</em> to delay 229 * the test until the expired messages are collected. 230 * 231 * @jmscts.requirement message.expiration.zero 232 * @jmscts.requirement message.expiration.expired 233 * @jmscts.factory TopicConnectionFactory 234 * @jmscts.factory XATopicConnectionFactory 235 * @jmscts.delivery administered-consumer 236 * @jmscts.durableonly true 237 * @jmscts.message MapMessage 238 * @throws Exception for any error 239 */ 240 public void testExpiration2DiffSubscribers() throws Exception { 241 final long timeToLive = 1000; // i.e, 1 second 242 final int messages = 10; // no. of messages to send 243 244 TestContext context = getContext(); 245 MessageReceiver[] subscribers = new MessageReceiver[2]; 246 247 // create a context for the non-durable subscriber 248 MessagingBehaviour behaviour = new MessagingBehaviour( 249 context.getMessagingBehaviour()); 250 behaviour.setDurable(false); 251 TestContext nondurable = TestContextHelper.createSendReceiveContext( 252 context, false, behaviour); 253 254 try { 255 subscribers[0] = createReceiver(DESTINATION); // durable subscriber 256 subscribers[1] = createReceiver(nondurable, DESTINATION); 257 checkExpiration(timeToLive, messages, subscribers); 258 } finally { 259 close(subscribers); 260 nondurable.close(); 261 } 262 } 263 264 /*** 265 * Sends <code>messageCount</code> messages with time-to-live 266 * <code>timeToLive</code>, and <code>messageCount</code> messages which 267 * don't expire, and verifies that after sleeping 268 * <code>timeToLive + EXPIRATION_INTERVAL</code> milliseconds, only the 269 * non-expiring messages may be received 270 * 271 * @param timeToLive the time-to-live for the expiring messages 272 * @param messageCount the no. of messages to send 273 * @param receiverCount the no. of receivers. For queues, should be 1. 274 * @throws Exception for any error 275 */ 276 private void checkExpiration(long timeToLive, int messageCount, 277 int receiverCount) throws Exception { 278 MessageReceiver[] receivers = new MessageReceiver[receiverCount]; 279 280 try { 281 for (int i = 0; i < receivers.length; ++i) { 282 receivers[i] = createReceiver(DESTINATION); 283 } 284 checkExpiration(timeToLive, messageCount, receivers); 285 } finally { 286 close(receivers); 287 } 288 } 289 290 /*** 291 * Sends <code>messageCount</code> messages with time-to-live 292 * <code>timeToLive</code>, and <code>messageCount</code> messages which 293 * don't expire, and verifies that after sleeping 294 * <code>timeToLive + EXPIRATION_INTERVAL</code> milliseconds, only the 295 * non-expiring messages may be received 296 * 297 * @param timeToLive the time-to-live for the expiring messages 298 * @param messageCount the no. of messages to send 299 * @param receivers the receivers to use. 300 * @throws Exception for any error 301 */ 302 private void checkExpiration(long timeToLive, int messageCount, 303 MessageReceiver[] receivers) 304 throws Exception { 305 TestContext context = getContext(); 306 Session session = context.getSession(); 307 Message message = context.getMessage(); 308 HashSet expiringIds = new HashSet(); 309 HashSet nonExpiringIds = new HashSet(); 310 311 MessageSender sender = null; 312 313 try { 314 sender = createSender(DESTINATION); 315 316 // send messages that expire 317 for (int i = 0; i < messageCount; ++i) { 318 sender.send(message, 1, timeToLive); 319 expiringIds.add(message.getJMSMessageID()); 320 } 321 322 // send messages that don't expire 323 for (int i = 0; i < messageCount; ++i) { 324 sender.send(message, 1, Message.DEFAULT_TIME_TO_LIVE); 325 nonExpiringIds.add(message.getJMSMessageID()); 326 } 327 328 if (session.getTransacted()) { 329 session.commit(); 330 } 331 332 assertEquals("Duplicate JMSMessageID allocated", messageCount, 333 expiringIds.size()); 334 335 assertEquals("Duplicate JMSMessageID allocated", messageCount, 336 nonExpiringIds.size()); 337 338 // now wait to allow the messages to expire. All of the non 339 // expiring messages should be received, and none of the expiring 340 // messages 341 long sleepTime = EXPIRATION_INTERVAL + timeToLive; 342 try { 343 log.debug("Sleeping for " + sleepTime 344 + "ms to allow messages to expire"); 345 Thread.currentThread().sleep(sleepTime); 346 } catch (InterruptedException ignore) { 347 // no-op 348 } 349 350 for (int i = 0; i < receivers.length; ++i) { 351 List messages = receive(receivers[i], messageCount); 352 Iterator iterator = messages.iterator(); 353 while (iterator.hasNext()) { 354 Message received = (Message) iterator.next(); 355 String id = received.getJMSMessageID(); 356 if (!nonExpiringIds.contains(id)) { 357 if (expiringIds.contains(id)) { 358 fail("Received a message which should have " 359 + "expired: " + id); 360 } else { 361 fail("Received a message which wasn't sent by this" 362 + " test: " + id); 363 } 364 } 365 } 366 } 367 } finally { 368 close(sender); 369 } 370 } 371 372 }

This page was automatically generated by Maven