/** * Copyright 2012 Comcast Corporation * * Licensed 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 com.comcast.cqs.test.unit; import org.junit.Test; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.HashMap; import java.util.Map; import org.junit.After; import org.junit.Before; import com.amazonaws.services.sqs.AmazonSQSClient; import com.amazonaws.services.sqs.model.DeleteMessageRequest; import com.amazonaws.services.sqs.model.DeleteQueueRequest; import com.amazonaws.services.sqs.model.ReceiveMessageRequest; import com.amazonaws.services.sqs.model.ReceiveMessageResult; import com.amazonaws.services.sqs.model.SendMessageRequest; import com.comcast.cmb.common.controller.CMBControllerServlet; import com.comcast.cmb.common.persistence.PersistenceFactory; import com.comcast.cmb.test.tools.CMBAWSBaseTest; public class CQSDCFailoverTest extends CMBAWSBaseTest { private AmazonSQSClient currentSqs = null; private static String queueUrl; private static Map<String, String> messageMap; @Before public void setup() throws Exception { super.setup(); PersistenceFactory.reset(); messageMap = new HashMap<String, String>(); try { currentSqs = cqs1; queueUrl = getQueueUrl(1, USR.USER1); Thread.sleep(1000); } catch (Exception ex) { logger.error("setup failed", ex); fail("setup failed: "+ex); return; } } @After public void tearDown() { CMBControllerServlet.valueAccumulator.deleteAllCounters(); if (queueUrl != null) { currentSqs.deleteQueue(new DeleteQueueRequest(queueUrl)); } } private class MultiMessageSender extends Thread { private int count; public MultiMessageSender(int count) { this.count = count; } public void run() { try { logger.info("starting sending messages"); for (int i=0; i<count; i++) { currentSqs.sendMessage(new SendMessageRequest(queueUrl, "test message " + i)); } } catch (Exception ex) { logger.error("error", ex); } } } /** * Test simulating a DC-failover while sending a total of 5000 messages into a single queue. This * test requires that sqs and alternateSqs point to two separate api servers using two separate redis * instances but using a shared cassandra ring. */ @Test public void testDCFailover() { if (cqsAlt == null) { logger.info("skipping dc failover test due to missing alternate sqs service url"); return; } try { int NUM_MESSAGES = 1000; (new MultiMessageSender(NUM_MESSAGES)).start(); Thread.sleep(2000); int messageCounter = 0; long begin = System.currentTimeMillis(); boolean messageFound = false; logger.info("starting receiving messages"); int readFailures = 0; while (messageCounter < NUM_MESSAGES || messageFound) { try { // flip to second data center half-way through the test if (messageCounter >= NUM_MESSAGES/2 && currentSqs == cqs1) { currentSqs = cqsAlt; logger.info("switching to secondary data center"); } ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(); receiveMessageRequest.setQueueUrl(queueUrl); receiveMessageRequest.setMaxNumberOfMessages(1); ReceiveMessageResult receiveMessageResult = currentSqs.receiveMessage(receiveMessageRequest); if (receiveMessageResult.getMessages().size() == 1) { messageCounter += receiveMessageResult.getMessages().size(); messageMap.put(receiveMessageResult.getMessages().get(0).getBody(), ""); DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest(); deleteMessageRequest.setQueueUrl(queueUrl); deleteMessageRequest.setReceiptHandle(receiveMessageResult.getMessages().get(0).getReceiptHandle()); currentSqs.deleteMessage(deleteMessageRequest); messageFound = true; logger.info("receiving message " + messageCounter); } else { messageFound = false; } } catch (Exception ex) { logger.error("read failure", ex); readFailures++; } } long end = System.currentTimeMillis(); logger.info("duration=" + (end-begin)); assertTrue("wrong number of messages: " + messageMap.size(), messageMap.size() == NUM_MESSAGES); assertTrue("read failures: " + readFailures, readFailures == 0); } catch (Exception ex) { ex.printStackTrace(); } } }