private function createPresignedUrl(AwsClientInterface $client, CommandInterface $cmd)
 {
     $newCmd = $client->getCommand('CopySnapshot', $cmd->toArray());
     // Avoid infinite recursion by flagging the new command.
     $newCmd->__skipCopySnapshot = true;
     // Serialize a request for the CopySnapshot operation.
     $request = \ILAB_Aws\serialize($newCmd);
     // Create the new endpoint for the target endpoint.
     $endpoint = EndpointProvider::resolve($this->endpointProvider, ['region' => $cmd['SourceRegion'], 'service' => 'ec2'])['endpoint'];
     // Set the request to hit the target endpoint.
     $uri = $request->getUri()->withHost((new Uri($endpoint))->getHost());
     $request = $request->withUri($uri);
     // Create a presigned URL for our generated request.
     $signer = new SignatureV4('ec2', $cmd['SourceRegion']);
     return (string) $signer->presign(SignatureV4::convertPostToGet($request), $client->getCredentials()->wait(), '+1 hour')->getUri();
 }
 /**
  * The CommandPool constructor accepts a hash of configuration options:
  *
  * - concurrency: (callable|int) Maximum number of commands to execute
  *   concurrently. Provide a function to resize the pool dynamically. The
  *   function will be provided the current number of pending requests and
  *   is expected to return an integer representing the new pool size limit.
  * - before: (callable) function to invoke before sending each command. The
  *   before function accepts the command and the key of the iterator of the
  *   command. You can mutate the command as needed in the before function
  *   before sending the command.
  * - fulfilled: (callable) Function to invoke when a promise is fulfilled.
  *   The function is provided the result object, id of the iterator that the
  *   result came from, and the aggregate promise that can be resolved/rejected
  *   if you need to short-circuit the pool.
  * - rejected: (callable) Function to invoke when a promise is rejected.
  *   The function is provided an AwsException object, id of the iterator that
  *   the exception came from, and the aggregate promise that can be
  *   resolved/rejected if you need to short-circuit the pool.
  *
  * @param AwsClientInterface $client   Client used to execute commands.
  * @param array|\Iterator    $commands Iterable that yields commands.
  * @param array              $config   Associative array of options.
  */
 public function __construct(AwsClientInterface $client, $commands, array $config = [])
 {
     if (!isset($config['concurrency'])) {
         $config['concurrency'] = 25;
     }
     $before = $this->getBefore($config);
     $mapFn = function ($commands) use($client, $before) {
         foreach ($commands as $key => $command) {
             if (!$command instanceof CommandInterface) {
                 throw new \InvalidArgumentException('Each value yielded by ' . 'the iterator must be an Aws\\CommandInterface.');
             }
             if ($before) {
                 $before($command, $key);
             }
             (yield $client->executeAsync($command));
         }
     };
     $this->each = new EachPromise($mapFn($commands), $config);
 }
 private function flushQueue()
 {
     static $validKeys = ['Key' => true, 'VersionId' => true];
     if (count($this->queue) === 0) {
         return null;
     }
     $batch = [];
     while ($obj = array_shift($this->queue)) {
         $batch[] = array_intersect_key($obj, $validKeys);
     }
     $command = $this->client->getCommand('DeleteObjects', ['Bucket' => $this->bucket, 'Delete' => ['Objects' => $batch]]);
     if ($this->before) {
         call_user_func($this->before, $command);
     }
     return $this->client->executeAsync($command)->then(function ($result) {
         if (!empty($result['Errors'])) {
             throw new DeleteMultipleObjectsException($result['Deleted'] ?: [], $result['Errors']);
         }
         return $result;
     });
 }