EVOLUTION-MANAGER
Edit File: AwsResourceIterator.php
<?php /** * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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. */ namespace DuplicatorPro\Aws\Common\Iterator; use DuplicatorPro\Aws\Common\Enum\UaString as Ua; use DuplicatorPro\Aws\Common\Exception\RuntimeException; Use DuplicatorPro\Guzzle\Service\Resource\Model; use DuplicatorPro\Guzzle\Service\Resource\ResourceIterator; /** * Iterate over a client command */ class AwsResourceIterator extends ResourceIterator { /** * @var Model Result of a command */ protected $lastResult = null; /** * Provides access to the most recent result obtained by the iterator. This makes it easier to extract any * additional information from the result which you do not have access to from the values emitted by the iterator * * @return Model|null */ public function getLastResult() { return $this->lastResult; } /** * {@inheritdoc} * This AWS specific version of the resource iterator provides a default implementation of the typical AWS iterator * process. It relies on configuration and extension to implement the operation-specific logic of handling results * and nextTokens. This method will loop until resources are acquired or there are no more iterations available. */ protected function sendRequest() { do { // Prepare the request including setting the next token $this->prepareRequest(); if ($this->nextToken) { $this->applyNextToken(); } // Execute the request and handle the results $this->command->add(Ua::OPTION, Ua::ITERATOR); $this->lastResult = $this->command->getResult(); $resources = $this->handleResults($this->lastResult); $this->determineNextToken($this->lastResult); // If no resources collected, prepare to reiterate before yielding if ($reiterate = empty($resources) && $this->nextToken) { $this->command = clone $this->originalCommand; } } while ($reiterate); return $resources; } protected function prepareRequest() { // Get the limit parameter key to set $limitKey = $this->get('limit_key'); if ($limitKey && ($limit = $this->command->get($limitKey))) { $pageSize = $this->calculatePageSize(); // If the limit of the command is different than the pageSize of the iterator, use the smaller value if ($limit && $pageSize) { $realLimit = min($limit, $pageSize); $this->command->set($limitKey, $realLimit); } } } protected function handleResults(Model $result) { $results = array(); // Get the result key that contains the results if ($resultKey = $this->get('result_key')) { $results = $this->getValueFromResult($result, $resultKey) ?: array(); } return $results; } protected function applyNextToken() { // Get the token parameter key to set if ($tokenParam = $this->get('input_token')) { // Set the next token. Works with multi-value tokens if (is_array($tokenParam)) { if (is_array($this->nextToken) && count($tokenParam) === count($this->nextToken)) { foreach (array_combine($tokenParam, $this->nextToken) as $param => $token) { $this->command->set($param, $token); } } else { throw new RuntimeException('The definition of the iterator\'s token parameter and the actual token ' . 'value are not compatible.'); } } else { $this->command->set($tokenParam, $this->nextToken); } } } protected function determineNextToken(Model $result) { $this->nextToken = null; // If the value of "more_results" is true or there is no "more_results" to check, then try to get the next token $moreKey = $this->get('more_results'); if ($moreKey === null || $this->getValueFromResult($result, $moreKey)) { // Get the token key to check if ($tokenKey = $this->get('output_token')) { // Get the next token's value. Works with multi-value tokens if (is_array($tokenKey)) { $this->nextToken = array(); foreach ($tokenKey as $key) { $this->nextToken[] = $this->getValueFromResult($result, $key); } } else { $this->nextToken = $this->getValueFromResult($result, $tokenKey); } } } } /** * Extracts the value from the result using Collection::getPath. Also adds some additional logic for keys that need * to access n-1 indexes (e.g., ImportExport, Kinesis). The n-1 logic only works for the known cases. We will switch * to a jmespath implementation in the future to cover all cases * * @param Model $result * @param string $key * * @return mixed|null */ protected function getValueFromResult(Model $result, $key) { // Special handling for keys that need to access n-1 indexes if (strpos($key, '#') !== false) { $keyParts = explode('#', $key, 2); $items = $result->getPath(trim($keyParts[0], '/')); if ($items && is_array($items)) { $index = count($items) - 1; $key = strtr($key, array('#' => $index)); } } // Get the value return $result->getPath($key); } }