Overview
  • Namespace
  • Class

Namespaces

  • OpenCloud
    • Autoscale
      • Resource
    • CloudMonitoring
      • Collection
      • Exception
      • Resource
    • Common
      • Collection
      • Constants
      • Exceptions
      • Http
        • Message
      • Log
      • Resource
      • Service
    • Compute
      • Constants
      • Exception
      • Resource
    • Database
      • Resource
    • DNS
      • Collection
      • Resource
    • Identity
      • Constants
      • Resource
    • Image
      • Enum
      • Resource
        • JsonPatch
        • Schema
    • LoadBalancer
      • Collection
      • Enum
      • Resource
    • Networking
      • Resource
    • ObjectStore
      • Constants
      • Exception
      • Resource
      • Upload
    • Orchestration
      • Resource
    • Queues
      • Collection
      • Exception
      • Resource
    • Volume
      • Resource

Classes

  • OpenCloud\Volume\Resource\Snapshot
  • OpenCloud\Volume\Resource\Volume
  • OpenCloud\Volume\Resource\VolumeType
  1 <?php
  2 /**
  3  * Copyright 2012-2014 Rackspace US, Inc.
  4  *
  5  * Licensed under the Apache License, Version 2.0 (the "License");
  6  * you may not use this file except in compliance with the License.
  7  * You may obtain a copy of the License at
  8  *
  9  * http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  */
 17 
 18 namespace OpenCloud\ObjectStore\Upload;
 19 
 20 use Guzzle\Batch\BatchBuilder;
 21 use Guzzle\Common\Collection;
 22 use Guzzle\Http\Message\Response;
 23 use Guzzle\Http\Url;
 24 use OpenCloud\ObjectStore\Resource\Container;
 25 
 26 /**
 27  * Class responsible for migrating the contents of one container to another
 28  *
 29  * @package OpenCloud\ObjectStore\Upload
 30  */
 31 class ContainerMigration
 32 {
 33     /** @var \Guzzle\Batch\Batch */
 34     protected $readQueue;
 35 
 36     /** @var \Guzzle\Batch\Batch */
 37     protected $writeQueue;
 38 
 39     /** @var \OpenCloud\ObjectStore\Resource\Container */
 40     protected $oldContainer;
 41 
 42     /** @var \OpenCloud\ObjectStore\Resource\Container */
 43     protected $newContainer;
 44 
 45     /** @var \Guzzle\Common\Collection */
 46     protected $options = array();
 47 
 48     protected $defaults = array(
 49         'read.batchLimit'  => 1000,
 50         'read.pageLimit'   => 10000,
 51         'write.batchLimit' => 100
 52     );
 53 
 54     /**
 55      * @param Container $old     Source container
 56      * @param Container $new     Target container
 57      * @param array     $options Options that configure process
 58      * @return ContainerMigration
 59      */
 60     public static function factory(Container $old, Container $new, array $options = array())
 61     {
 62         $migration = new self();
 63 
 64         $migration->setOldContainer($old);
 65         $migration->setNewContainer($new);
 66         $migration->setOptions($options);
 67 
 68         $migration->setupReadQueue();
 69         $migration->setupWriteQueue();
 70 
 71         return $migration;
 72     }
 73 
 74     /**
 75      * @param Container $old
 76      */
 77     public function setOldContainer(Container $old)
 78     {
 79         $this->oldContainer = $old;
 80     }
 81 
 82     /**
 83      * @return Container
 84      */
 85     public function getOldContainer()
 86     {
 87         return $this->oldContainer;
 88     }
 89 
 90     /**
 91      * @param Container $new
 92      */
 93     public function setNewContainer(Container $new)
 94     {
 95         $this->newContainer = $new;
 96     }
 97 
 98     /**
 99      * @return Container
100      */
101     public function getNewContainer()
102     {
103         return $this->newContainer;
104     }
105 
106     /**
107      * @param array $options
108      */
109     public function setOptions(array $options)
110     {
111         $this->options = Collection::fromConfig($options, $this->defaults);
112     }
113 
114     /**
115      * @return \Guzzle\Common\Collection
116      */
117     public function getOptions()
118     {
119         return $this->options;
120     }
121 
122     /**
123      * Set the read queue as a {@see \Guzzle\Batch\Batch} queue using the {@see \Guzzle\Batch\BatchBuilder}
124      */
125     public function setupReadQueue()
126     {
127         $this->readQueue = BatchBuilder::factory()
128             ->transferRequests($this->options->get('read.batchLimit'))
129             ->build();
130     }
131 
132     /**
133      * Set the write queue as a {@see \Guzzle\Batch\Batch} queue using the {@see \Guzzle\Batch\BatchBuilder}
134      */
135     public function setupWriteQueue()
136     {
137         $this->writeQueue = BatchBuilder::factory()
138             ->transferRequests($this->options->get('write.batchLimit'))
139             ->build();
140     }
141 
142     /**
143      * @return \Guzzle\Http\ClientInterface
144      */
145     private function getClient()
146     {
147         return $this->newContainer->getService()->getClient();
148     }
149 
150     /**
151      * Create a collection of files to be migrated and add them to the read queue
152      */
153     protected function enqueueGetRequests()
154     {
155         $files = $this->oldContainer->objectList(array(
156             'limit.total' => false,
157             'limit.page'  => $this->options->get('read.pageLimit')
158         ));
159 
160         foreach ($files as $file) {
161             $this->readQueue->add(
162                 $this->getClient()->get($file->getUrl())
163             );
164         }
165     }
166 
167     /**
168      * Send the read queue (in order to gather more information about individual files)
169      *
170      * @return array Responses
171      */
172     protected function sendGetRequests()
173     {
174         $this->enqueueGetRequests();
175 
176         return $this->readQueue->flush();
177     }
178 
179     /**
180      * Create a tailored PUT request for each file
181      *
182      * @param Response $response
183      * @return \Guzzle\Http\Message\EntityEnclosingRequestInterface
184      */
185     protected function createPutRequest(Response $response)
186     {
187         $segments = Url::factory($response->getEffectiveUrl())->getPathSegments();
188         $name = end($segments);
189 
190         // Retrieve content and metadata
191         $file = $this->newContainer->dataObject()->setName($name);
192         $file->setMetadata($response->getHeaders(), true);
193 
194         return $this->getClient()->put(
195             $file->getUrl(),
196             $file::stockHeaders($file->getMetadata()->toArray()),
197             $response->getBody()
198         );
199     }
200 
201     /**
202      * Initiate the transfer process
203      *
204      * @return array PUT responses
205      */
206     public function transfer()
207     {
208         $requests = $this->sendGetRequests();
209         $this->readQueue = null;
210 
211         foreach ($requests as $key => $request) {
212             $this->writeQueue->add(
213                 $this->createPutRequest($request->getResponse())
214             );
215             unset($requests[$key]);
216         }
217 
218         return $this->writeQueue->flush();
219     }
220 }
221 
API documentation generated by ApiGen