예제 #1
0
 public function testBasicOperations()
 {
     // Create a queue and make sure everything goes OK
     $queueName = 'php-integ-sqs-queue-' . time();
     self::log('Create an SQS queue.');
     $result = $this->sqs->getCommand('CreateQueue', array('QueueName' => $queueName, 'Attributes' => array(QueueAttribute::RECEIVE_MESSAGE_WAIT_TIME_SECONDS => 20, QueueAttribute::DELAY_SECONDS => 10)))->getResult();
     $createdQueueUrl = $result->get('QueueUrl');
     self::log('Get the queue URL.');
     do {
         try {
             $result = $this->sqs->getCommand('GetQueueUrl', array('QueueName' => $queueName))->getResult();
             $queueUrl = $result->get('QueueUrl');
         } catch (SqsException $e) {
             $queueUrl = null;
             sleep(2);
         }
     } while (!$queueUrl);
     $this->assertEquals($createdQueueUrl, $queueUrl);
     self::log('Get the queue attributes.');
     $result = $this->sqs->getCommand('GetQueueAttributes', array('QueueUrl' => $queueUrl, 'AttributeNames' => array(QueueAttribute::ALL)))->getResult();
     $this->assertEquals(20, $result->getPath('Attributes/' . QueueAttribute::RECEIVE_MESSAGE_WAIT_TIME_SECONDS));
     $this->assertEquals(10, $result->getPath('Attributes/' . QueueAttribute::DELAY_SECONDS));
     self::log('Make sure the custom ARN-calculating logic returns the actual ARN.');
     $this->assertEquals($this->sqs->getQueueArn($queueUrl), $result->getPath('Attributes/' . QueueAttribute::QUEUE_ARN));
     // Send, receive, and delete messages
     $messagesToDelete = array();
     self::log('Send a message with no delay to the queue.');
     $this->sqs->getCommand('SendMessage', array('QueueUrl' => $queueUrl, 'MessageBody' => 'test message 1', 'DelaySeconds' => 0, 'VisibilityTimeout' => 300))->execute();
     self::log('Receive a message from the queue.');
     $result = $this->sqs->getCommand('ReceiveMessage', array('QueueUrl' => $queueUrl, 'AttributeNames' => array(MessageAttribute::ALL)))->getResult();
     $messages = $result->get('Messages');
     $this->assertCount(1, $messages);
     $message = $messages[0];
     $this->assertEquals('test message 1', $message['Body']);
     $this->assertCount(4, $message['Attributes']);
     // Make sure attributes are unmarshalled correctly
     $messagesToDelete[] = array('Id' => str_replace(' ', '-', $message['Body']), 'ReceiptHandle' => $message['ReceiptHandle']);
     self::log('Send and receive a delayed message and make sure long polling is working. Please wait.');
     $startTime = microtime(true);
     $this->sqs->getCommand('SendMessage', array('QueueUrl' => $queueUrl, 'MessageBody' => 'test message 2'))->execute();
     $result = $this->sqs->getCommand('ReceiveMessage', array('QueueUrl' => $queueUrl))->getResult();
     $endTime = microtime(true);
     $this->assertGreaterThan(5, $endTime - $startTime);
     $this->assertGreaterThanOrEqual(1, count($result->get('Messages')));
     $message = $result->getPath('Messages/0');
     $messagesToDelete[] = array('Id' => str_replace(' ', '-', $message['Body']), 'ReceiptHandle' => $message['ReceiptHandle']);
     self::log('Delete the messages using batch delete and verify that the deletions are successful.');
     $result = $this->sqs->getCommand('DeleteMessageBatch', array('QueueUrl' => $queueUrl, 'Entries' => $messagesToDelete))->getResult();
     $deletions = $result['Successful'];
     $this->assertCount(2, $deletions);
     foreach ($deletions as $deletion) {
         $this->assertRegExp('/^test\\-message\\-\\d$/', $deletion['Id']);
     }
     // Delete the queue
     self::log('Delete the queue.');
     $this->sqs->getCommand('DeleteQueue', array('QueueUrl' => $queueUrl))->execute();
 }
예제 #2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $noWatch = $input->getOption('no-watch');
     $queueId = $this->getQueueId();
     $snsConfig = $this->getContainer()->getParameter('sns');
     $region = isset($snsConfig['region']) ? $snsConfig['region'] : 'us-east-1';
     /** @var QueueFactory $queueFactory */
     $queueFactory = $this->getContainer()->get('syrup.queue_factory');
     $sqs = $queueFactory->create($queueId, $region, $snsConfig['key'], $snsConfig['secret']);
     /** @var Connection $conn */
     $conn = $this->getContainer()->get('doctrine.dbal.syrup_connection');
     $stmt = $conn->query("SELECT * FROM queues WHERE id='{$queueId}'");
     $res = $stmt->fetchAll();
     if (empty($res)) {
         $conn->insert('queues', ['id' => $queueId, 'access_key' => $snsConfig['key'], 'secret_key' => $snsConfig['secret'], 'region' => $region, 'url' => $sqs->get('QueueUrl')]);
     }
     $sqsClient = new SqsClient(['region' => $region, 'version' => '2012-11-05', 'credentials' => ['key' => $snsConfig['key'], 'secret' => $snsConfig['secret']]]);
     $sqsArn = $sqsClient->getQueueArn($sqs->get('QueueUrl'));
     // subscribe SQS to SNS
     $snsClient = new SnsClient(['region' => $region, 'version' => '2010-03-31', 'credentials' => ['key' => $snsConfig['key'], 'secret' => $snsConfig['secret']]]);
     $snsClient->subscribe(['TopicArn' => $snsConfig['topic_arn'], 'Protocol' => 'sqs', 'Endpoint' => $sqsArn]);
     // add policy to SQS to allow SNS sending messages to it
     $sqsPolicy = '{
       "Version": "2008-10-17",
       "Id": "' . $sqsArn . '/SQSDefaultPolicy",
       "Statement": [
         {
           "Sid": "sqs-sns",
           "Effect": "Allow",
           "Principal": {
             "AWS": "*"
           },
           "Action": "SQS:SendMessage",
           "Resource": "' . $sqsArn . '",
           "Condition": {
             "ArnEquals": {
               "aws:SourceArn": "' . $snsConfig['topic_arn'] . '"
             }
           }
         }
       ]
     }';
     $sqsClient->setQueueAttributes(['QueueUrl' => $sqs->get('QueueUrl'), 'Attributes' => ['Policy' => $sqsPolicy]]);
     $output->writeln("SQS created and registered to SNS");
     // Add Cloudwatch alarm
     if (!$noWatch) {
         $cwClient = new CloudWatchClient(['region' => $region, 'version' => '2010-08-01', 'credentials' => ['key' => $snsConfig['key'], 'secret' => $snsConfig['secret']]]);
         $cwClient->putMetricAlarm(['AlarmName' => sprintf('Syrup %s queue is full', $queueId), 'ActionsEnabled' => true, 'AlarmActions' => [$snsConfig['alarm_topic_arn']], 'MetricName' => 'ApproximateNumberOfMessagesVisible', 'Namespace' => 'AWS/SQS', 'Statistic' => 'Average', 'Dimensions' => [['Name' => 'QueueName', 'Value' => $queueId]], 'Period' => 300, 'EvaluationPeriods' => 1, 'Threshold' => 5, 'ComparisonOperator' => 'GreaterThanOrEqualToThreshold']);
         $output->writeln("Cloudwatch alarm created");
     }
 }
예제 #3
0
 /**
  * @depends testCreatesTopic
  */
 public function testSubscribesToTopic($topicArn)
 {
     // Create an SQS queue for the test
     self::log('Creating a SQS queue');
     $result = $this->sqs->createQueue(array('QueueName' => self::$queueName));
     self::$queueUrl = $result['QueueUrl'];
     $queueArn = $this->sqs->getQueueArn(self::$queueUrl);
     // Subscribe to the SNS topic using an SQS queue
     self::log('Subscribing to the topic using the queue');
     $result = $this->sns->subscribe(array('TopicArn' => self::$topicArn, 'Endpoint' => $queueArn, 'Protocol' => 'sqs'));
     // Ensure that the result has a SubscriptionArn
     self::log('Subscribe result: ' . var_export($result->toArray(), true));
     $this->assertArrayHasKey('SubscriptionArn', $result->toArray());
     self::$subscriptionArn = $result['SubscriptionArn'];
     return self::$subscriptionArn;
 }
예제 #4
0
 /**
  * Checks to see if a Topic exists
  *
  * This method relies on in-memory cache and the Cache provider
  * to reduce the need to needlessly call the create method on an existing
  * Topic.
  *
  * @return boolean
  */
 public function topicExists()
 {
     if (isset($this->topicArn)) {
         return true;
     }
     $key = $this->getNameWithPrefix() . '_arn';
     if ($this->cache->contains($key)) {
         $this->topicArn = $this->cache->fetch($key);
         return true;
     }
     if (!empty($this->queueUrl)) {
         $queueArn = $this->sqs->getQueueArn($this->queueUrl);
         $topicArn = str_replace('sqs', 'sns', $queueArn);
         try {
             $this->sns->getTopicAttributes(['TopicArn' => $topicArn]);
         } catch (SnsException $e) {
             return false;
         }
         $this->topicArn = $topicArn;
         $this->cache->save($key, $this->topicArn);
         return true;
     }
     return false;
 }
예제 #5
0
 /**
  * Creates a Policy for SQS that's required to allow SNS SendMessage access
  *
  * @return string
  */
 public function createSqsPolicy()
 {
     $arn = $this->sqs->getQueueArn($this->queueUrl);
     return json_encode(['Version' => '2008-10-17', 'Id' => sprintf('%s/SQSDefaultPolicy', $arn), 'Statement' => [['Sid' => 'SNSPermissions', 'Effect' => 'Allow', 'Principal' => ['AWS' => '*'], 'Action' => 'SQS:SendMessage', 'Resource' => $arn]]]);
 }