1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 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 28 29 30
31 class ContainerMigration
32 {
33
34 protected $readQueue;
35
36
37 protected $writeQueue;
38
39
40 protected $oldContainer;
41
42
43 protected $newContainer;
44
45
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 56 57 58 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 76
77 public function setOldContainer(Container $old)
78 {
79 $this->oldContainer = $old;
80 }
81
82 83 84
85 public function getOldContainer()
86 {
87 return $this->oldContainer;
88 }
89
90 91 92
93 public function setNewContainer(Container $new)
94 {
95 $this->newContainer = $new;
96 }
97
98 99 100
101 public function getNewContainer()
102 {
103 return $this->newContainer;
104 }
105
106 107 108
109 public function setOptions(array $options)
110 {
111 $this->options = Collection::fromConfig($options, $this->defaults);
112 }
113
114 115 116
117 public function getOptions()
118 {
119 return $this->options;
120 }
121
122 123 124
125 public function setupReadQueue()
126 {
127 $this->readQueue = BatchBuilder::factory()
128 ->transferRequests($this->options->get('read.batchLimit'))
129 ->build();
130 }
131
132 133 134
135 public function setupWriteQueue()
136 {
137 $this->writeQueue = BatchBuilder::factory()
138 ->transferRequests($this->options->get('write.batchLimit'))
139 ->build();
140 }
141
142 143 144
145 private function getClient()
146 {
147 return $this->newContainer->getService()->getClient();
148 }
149
150 151 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 169 170 171
172 protected function sendGetRequests()
173 {
174 $this->enqueueGetRequests();
175
176 return $this->readQueue->flush();
177 }
178
179 180 181 182 183 184
185 protected function createPutRequest(Response $response)
186 {
187 $segments = Url::factory($response->getEffectiveUrl())->getPathSegments();
188 $name = end($segments);
189
190
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 203 204 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