package tw.com.integration; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sqs.AmazonSQSClient; import com.amazonaws.services.sqs.model.ReceiveMessageRequest; import com.amazonaws.services.sqs.model.ReceiveMessageResult; import org.apache.commons.cli.MissingArgumentException; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import tw.com.EnvironmentSetupForTests; import tw.com.entity.StackNotification; import tw.com.exceptions.FailedToCreateQueueException; import tw.com.exceptions.NotReadyException; import tw.com.providers.SNSEventSource; import java.util.List; import java.util.UUID; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class TestSNSEventSource { private static AmazonSNSClient snsClient; private static AmazonSQSClient sqsClient; SNSEventSource eventSource; @BeforeClass public static void beforeAllTestsRun() { DefaultAWSCredentialsProviderChain credentialsProvider = new DefaultAWSCredentialsProviderChain(); snsClient = EnvironmentSetupForTests.createSNSClient(credentialsProvider); sqsClient = EnvironmentSetupForTests.createSQSClient(credentialsProvider); } @Before public void beforeEachTestRuns() { eventSource = new SNSEventSource(snsClient, sqsClient); } @Test public void shouldThrowIfNotInit() { try { eventSource.receiveNotifications(); fail("should have thrown"); } catch(NotReadyException expectedException) { // expected } } @Test public void shouldCreateSNSAndSQSPlusPolicyAsNeeded() throws MissingArgumentException, NotReadyException, FailedToCreateQueueException, InterruptedException { eventSource.init(); String existingSNSARN = eventSource.getSNSArn(); // reset the queue, sns and subscription (this forces policy recreation as well) String sub = eventSource.getARNofSQSSubscriptionToSNS(); if (sub!=null) { snsClient.unsubscribe(sub); } snsClient.deleteTopic(existingSNSARN); sqsClient.deleteQueue(eventSource.getQueueURL()); // now recreate the source and make sure we can send/receive SNSEventSource anotherEventSource = new SNSEventSource(snsClient, sqsClient); anotherEventSource.init(); // should be able to send via sns and then receive from sqs if everything worked ok snsClient.publish(anotherEventSource.getSNSArn(), "aMessage"); ReceiveMessageRequest request = new ReceiveMessageRequest(). withQueueUrl(anotherEventSource.getQueueURL()). withWaitTimeSeconds(10); ReceiveMessageResult result = sqsClient.receiveMessage(request); assertTrue(result.getMessages().size()>0); } @Test public void shouldReceiveNotifications() throws MissingArgumentException, NotReadyException, FailedToCreateQueueException, InterruptedException { String stackId = UUID.randomUUID().toString(); String messageContents = String.format("StackName='temporaryStack'\nStackId='%s'\nEventId='9afc1e30-9eff-11e3-b6e7-506cf935a496'\nLogicalResourceId='temporaryStack'\nPhysicalResourceId='arn:aws:cloudformation:eu-west-1:619378453009:stack/temporaryStack/8c343e50-9eff-11e3-b6e7-506cf935a496'\nResourceType='AWS::CloudFormation::Stack'\nTimestamp='2014-02-26T16:04:00.438Z'\nResourceStatus='CREATE_COMPLETE'\nResourceStatusReason=''\nResourceProperties=''\n", stackId); eventSource.init(); String topicArn = eventSource.getSNSArn(); snsClient.publish(topicArn, "willNotParse"); snsClient.publish(topicArn, messageContents); snsClient.publish(topicArn, "AlsoWillNotParse"); int attempts = 10; boolean found = false; while((attempts>0) && (!found)) { List<StackNotification> results = eventSource.receiveNotifications(); for(StackNotification candidate : results) { if (stackId.equals(candidate.getStackId())) { found = true; break; } } attempts--; } assertTrue(found); } }