/**
  * @return array Data for testTransfersBatches
  */
 public function getTransferBatchesData()
 {
     // Mock objects for 3rd test case
     $mockRequest = $this->getMockBuilder('Guzzle\\Http\\Message\\EntityEnclosingRequestInterface')->disableOriginalConstructor()->getMock();
     $mockRequest->expects($this->any())->method('getBody')->will($this->onConsecutiveCalls('{"RequestItems":{"foo":[{"PutRequest":{}},{"PutRequest":{}}]}}', '{"RequestItems":{}}', '{"RequestItems":{}}'));
     $mockResponse = $this->getMockBuilder('Guzzle\\Http\\Message\\Response')->disableOriginalConstructor()->getMock();
     $mockResponse->expects($this->any())->method('getStatusCode')->will($this->returnValue(413));
     $tooBigException = new DynamoDbException();
     $tooBigException->setResponse($mockResponse);
     $tooBigException->setRequest($mockRequest);
     $exceptionCollection = new ExceptionCollection();
     $exceptionCollection->add($tooBigException);
     // Mock objects for 4th use case
     $exceptionCollectionWithDummy = new ExceptionCollection();
     $exceptionCollectionWithDummy->add(new \RuntimeException());
     // Provisioned throughput exceeded use case (#6)
     $throughputExceededException = new DynamoDbException();
     $throughputExceededException->setExceptionCode('ProvisionedThroughputExceededException');
     $mockRequestPTE = $this->getMockBuilder('Guzzle\\Http\\Message\\EntityEnclosingRequestInterface')->disableOriginalConstructor()->getMock();
     $mockRequestPTE->expects($this->any())->method('getBody')->will($this->returnValue('{"RequestItems":{"foo":[{"PutRequest":{}},{"PutRequest":{}}]}}'));
     $throughputExceededException->setRequest($mockRequestPTE);
     $exceptionCollectionThroughput = new ExceptionCollection();
     $exceptionCollectionThroughput->add($throughputExceededException);
     // Some DynamoDbException that will be rethrown, not handled (case #7)
     $unhandledDynamoDbException = new DynamoDbException();
     $unhandledDynamoDbException->setExceptionCode('UnhandledException');
     $exceptionCollectionUnhandled = new ExceptionCollection();
     $exceptionCollectionUnhandled->add($unhandledDynamoDbException);
     return array(array(array('UnprocessedItems' => array()), null, 'all-items-transferred'), array(array('UnprocessedItems' => array('foo' => array(array('foo')))), null, 'some-unprocessed-items'), array(array('UnprocessedItems' => array()), $this->throwException($exceptionCollection), 'all-items-transferred'), array(array('UnprocessedItems' => array()), $this->throwException($exceptionCollectionWithDummy), 'exceptions-thrown'), array(array('UnprocessedItems' => array()), $this->throwException($exceptionCollectionWithDummy), 'exceptions-thrown'), array(array('UnprocessedItems' => array()), $this->throwException($exceptionCollectionThroughput), 'some-unprocessed-items'), array(array('UnprocessedItems' => array()), $this->throwException($exceptionCollectionUnhandled), 'exceptions-thrown'));
 }
 public function testCanAddSelf()
 {
     $e1 = new ExceptionCollection();
     $e1->add(new \Exception("Test"));
     $e2 = new ExceptionCollection();
     $e2->add(new \Exception("Test 2"));
     $e1->add($e2);
     $this->assertEquals("Test\nTest 2", $e1->getMessage());
 }
 public function testCanAddSelf()
 {
     $e1 = new ExceptionCollection();
     $e1->add(new \Exception("Test"));
     $e2 = new ExceptionCollection('Meta description!');
     $e2->add(new \Exception("Test 2"));
     $e3 = new ExceptionCollection();
     $e3->add(new \Exception('Baz'));
     $e2->add($e3);
     $e1->add($e2);
     $message = $e1->getMessage();
     $this->assertEquals("(Exception) Test\n" . "(Guzzle\\Common\\Exception\\ExceptionCollection)\n" . "    Meta description!\n" . "    (Exception) Test 2\n" . "    (Guzzle\\Common\\Exception\\ExceptionCollection)\n" . "        (Exception) Baz", $message);
 }
 /**
  * Add exceptions to the collection
  *
  * @param ExceptionCollection|\Exception $e Exception to add
  *
  * @return ExceptionCollection;
  */
 public function add($e)
 {
     if ($e instanceof self) {
         foreach ($e as $exception) {
             $this->exceptions[] = $exception;
         }
     } elseif ($e instanceof \Exception) {
         $this->exceptions[] = $e;
     }
     $this->message = implode("\n", array_map(function ($e) {
         return $e->getMessage();
     }, $this->exceptions));
     return $this;
 }
 /**
  * Transfer a batch of requests and collect any unprocessed items
  *
  * @param array                             $batch               A batch of write requests
  * @param UnprocessedWriteRequestsException $unprocessedRequests Collection of unprocessed items
  *
  * @throws \Guzzle\Common\Exception\ExceptionCollection
  */
 protected function performTransfer(array $batch, UnprocessedWriteRequestsException $unprocessedRequests)
 {
     // Do nothing if the batch is empty
     if (empty($batch)) {
         return;
     }
     // Prepare an array of commands to be sent in parallel from the batch
     $commands = $this->prepareCommandsForBatchedItems($batch);
     // Execute the commands and handle exceptions
     try {
         $commands = $this->client->execute($commands);
         $this->getUnprocessedRequestsFromCommands($commands, $unprocessedRequests);
     } catch (ExceptionCollection $exceptions) {
         // Create a container exception for any unhandled (true) exceptions
         $unhandledExceptions = new ExceptionCollection();
         // Loop through caught exceptions and handle RequestTooLarge scenarios
         /** @var $e DynamoDbException */
         foreach ($exceptions as $e) {
             if ($e instanceof DynamoDbException) {
                 $request = $e->getRequest();
                 if ($e->getStatusCode() === 413) {
                     $this->retryLargeRequest($request, $unprocessedRequests);
                 } elseif ($e->getExceptionCode() === 'ProvisionedThroughputExceededException') {
                     $this->handleUnprocessedRequestsAfterException($request, $unprocessedRequests);
                 }
             } else {
                 $unhandledExceptions->add($e);
             }
         }
         // If there were unhandled exceptions, throw them
         if (count($unhandledExceptions)) {
             throw $unhandledExceptions;
         }
     }
 }
 public function testCanAddSelf()
 {
     $e1 = new ExceptionCollection();
     $e1->add(new \Exception("Test"));
     $e2 = new ExceptionCollection('Meta description!');
     $e2->add(new \Exception("Test 2"));
     $e3 = new ExceptionCollection();
     $e3->add(new \Exception('Baz'));
     $e2->add($e3);
     $e1->add($e2);
     $message = $e1->getMessage();
     $this->assertContains("(Exception) ./tests/Guzzle/Tests/Common/Exception/ExceptionCollectionTest.php line ", $message);
     $this->assertContains("\n    Test\n\n    #0 ", $message);
     $this->assertContains("\n\n(Guzzle\\Common\\Exception\\ExceptionCollection) ./tests/Guzzle/Tests/Common/Exception/ExceptionCollectionTest.php line ", $message);
     $this->assertContains("\n\n    Meta description!\n\n", $message);
     $this->assertContains("    (Exception) ./tests/Guzzle/Tests/Common/Exception/ExceptionCollectionTest.php line ", $message);
     $this->assertContains("\n        Test 2\n\n        #0 ", $message);
     $this->assertContains("        (Exception) ./tests/Guzzle/Tests/Common/Exception/ExceptionCollectionTest.php line ", $message);
     $this->assertContains("            Baz\n\n            #0", $message);
 }
 /**
  * {@inheritdoc}
  */
 public function send()
 {
     $this->scope++;
     // Don't prepare for sending again if send() is called while sending
     if ($this->state != self::STATE_SENDING) {
         $requests = $this->all();
         // Any exceptions thrown from this event should break the entire
         // flow of sending requests in parallel to prevent weird errors
         $this->dispatch(self::BEFORE_SEND, array('requests' => $requests));
         $this->state = self::STATE_SENDING;
         foreach ($requests as $request) {
             if ($request->getState() != RequestInterface::STATE_TRANSFER) {
                 $this->beforeSend($request);
             }
         }
     }
     try {
         $this->perform();
     } catch (\Exception $e) {
         $this->exceptions[] = $e;
     }
     $this->scope--;
     // Complete the transfer if this is the bottom scope and the state
     // of the curl multi handle is not already complete
     if ($this->state !== self::STATE_COMPLETE && $this->scope == -1) {
         $this->state = self::STATE_COMPLETE;
         $this->dispatch(self::COMPLETE);
         $this->state = self::STATE_IDLE;
     }
     if (!empty($this->exceptions)) {
         $collection = new ExceptionCollection('Errors during multi transfer');
         while ($e = array_shift($this->exceptions)) {
             $collection->add($e);
         }
         $this->reset();
         throw $collection;
     }
 }
Example #8
0
 /**
  * Clear the bucket
  *
  * @return int Returns the number of deleted keys
  * @throws ExceptionCollection
  */
 public function clear()
 {
     $that = $this;
     $batch = DeleteObjectsBatch::factory($this->client, $this->bucket, $this->mfa);
     $batch = new NotifyingBatch($batch, function ($items) use($that) {
         $that->dispatch(ClearBucket::AFTER_DELETE, array('keys' => $items));
     });
     $batch = new FlushingBatch(new ExceptionBufferingBatch($batch), 1000);
     // Let any listeners know that the bucket is about to be cleared
     $this->dispatch(self::BEFORE_CLEAR, array('iterator' => $this->getIterator(), 'batch' => $batch, 'mfa' => $this->mfa));
     $deleted = 0;
     foreach ($this->getIterator() as $object) {
         if (isset($object['VersionId'])) {
             $versionId = $object['VersionId'] == 'null' ? null : $object['VersionId'];
         } else {
             $versionId = null;
         }
         $batch->addKey($object['Key'], $versionId);
         $deleted++;
     }
     $batch->flush();
     // If any errors were encountered, then throw an ExceptionCollection
     if (count($batch->getExceptions())) {
         $e = new ExceptionCollection();
         foreach ($batch->getExceptions() as $exception) {
             $e->add($exception->getPrevious());
         }
         throw $e;
     }
     // Let any listeners know that the bucket was cleared
     $this->dispatch(self::AFTER_CLEAR, array('deleted' => $deleted));
     return $deleted;
 }
 /**
  * Transfer a batch of requests and collect any unprocessed items
  *
  * @param array                             $batch               A batch of write requests
  * @param UnprocessedWriteRequestsException $unprocessedRequests Collection of unprocessed items
  *
  * @throws \Guzzle\Common\Exception\ExceptionCollection
  */
 protected function performTransfer(array $batch, UnprocessedWriteRequestsException $unprocessedRequests)
 {
     // Do nothing if the batch is empty
     if (empty($batch)) {
         return;
     }
     // Chunk the array and prepare a set of parallel commands
     $commands = array();
     foreach (array_chunk($batch, self::BATCH_WRITE_MAX_SIZE) as $chunk) {
         // Convert the request items into the format required by the client
         $items = array();
         foreach ($chunk as $item) {
             if ($item instanceof AbstractWriteRequest) {
                 /** @var $item AbstractWriteRequest */
                 $table = $item->getTableName();
                 if (!isset($items[$table])) {
                     $items[$table] = array();
                 }
                 $items[$table][] = $item->toArray();
             }
         }
         // Create the BatchWriteItem request
         $commands[] = $this->client->getCommand('BatchWriteItem', array('RequestItems' => $items, Ua::OPTION => Ua::BATCH));
     }
     // Execute the commands and handle exceptions
     try {
         $commands = $this->client->execute($commands);
         $this->getUnprocessedRequestsFromCommands($commands, $unprocessedRequests);
     } catch (ExceptionCollection $exceptions) {
         // Create a container exception for any unhandled (true) exceptions
         $unhandledExceptions = new ExceptionCollection();
         // Loop through caught exceptions and handle RequestTooLarge scenarios
         /** @var $e DynamoDbException */
         foreach ($exceptions as $e) {
             if ($e instanceof DynamoDbException && $e->getStatusCode() === 413) {
                 $request = $e->getResponse()->getRequest();
                 $this->retryLargeRequest($request, $unprocessedRequests);
             } else {
                 $unhandledExceptions->add($e);
             }
         }
         // If there were unhandled exceptions, throw them
         if (count($unhandledExceptions)) {
             throw $unhandledExceptions;
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function send()
 {
     $this->scope++;
     $this->state = self::STATE_SENDING;
     // Only prepare and send requests that are in the current recursion scope
     // Only enter the main perform() loop if there are requests in scope
     if (!empty($this->requests[$this->scope])) {
         // Any exceptions thrown from this event should break the entire
         // flow of sending requests in parallel to prevent weird errors
         $this->dispatch(self::BEFORE_SEND, array('requests' => $this->requests[$this->scope]));
         foreach ($this->requests[$this->scope] as $request) {
             if ($request->getState() != RequestInterface::STATE_TRANSFER) {
                 $this->beforeSend($request);
             }
         }
         try {
             $this->perform();
         } catch (\Exception $e) {
             $this->exceptions[] = $e;
         }
     }
     $this->scope--;
     // Aggregate exceptions into an ExceptionCollection
     $exceptionCollection = null;
     if (!empty($this->exceptions)) {
         $exceptionCollection = new ExceptionCollection('Errors during multi transfer');
         while ($e = array_shift($this->exceptions)) {
             $exceptionCollection->add($e);
         }
     }
     // Complete the transfer if this is not a nested scope
     if ($this->scope == -1) {
         $this->state = self::STATE_COMPLETE;
         $this->dispatch(self::COMPLETE);
         $this->reset();
     }
     // Throw any exceptions that were encountered
     if ($exceptionCollection) {
         throw $exceptionCollection;
     }
 }