Skip to content

Commit 9cf0117

Browse files
committed
AliasProcessor
1 parent bb4618c commit 9cf0117

File tree

3 files changed

+305
-65
lines changed

3 files changed

+305
-65
lines changed

Exception/AliasIsIndexException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ class AliasIsIndexException extends \Exception
66
{
77
public function __construct($indexName)
88
{
9-
parent::__construct(sprintf('Expected alias %s instead of index', $indexName));
9+
parent::__construct(sprintf('Expected %s to be an alias but it is an index.', $indexName));
1010
}
1111
}

Index/AliasProcessor.php

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -54,37 +54,47 @@ public function switchIndexAlias(IndexConfig $indexConfig, Index $index, $force
5454
$client = $index->getClient();
5555

5656
$aliasName = $indexConfig->getElasticSearchName();
57-
$oldIndexName = false;
57+
$oldIndexName = null;
5858
$newIndexName = $index->getName();
5959

6060
try {
61-
$aliasedIndexes = $this->getAliasedIndexes($client, $aliasName);
61+
$oldIndexName = $this->getAliasedIndex($client, $aliasName);
6262
} catch (AliasIsIndexException $e) {
6363
if (!$force) {
6464
throw $e;
6565
}
6666

6767
$this->deleteIndex($client, $aliasName);
68-
$aliasedIndexes = array();
6968
}
7069

71-
if (count($aliasedIndexes) > 1) {
72-
throw new \RuntimeException(
73-
sprintf(
74-
'Alias %s is used for multiple indexes: [%s].
75-
Make sure it\'s either not used or is assigned to one index only',
76-
$aliasName,
77-
implode(', ', $aliasedIndexes)
78-
)
79-
);
70+
try {
71+
$aliasUpdateRequest = $this->buildAliasUpdateRequest($oldIndexName, $aliasName, $newIndexName);
72+
$client->request('_aliases', 'POST', $aliasUpdateRequest);
73+
} catch (ExceptionInterface $e) {
74+
$this->cleanupRenameFailure($client, $newIndexName, $e);
75+
}
76+
77+
// Delete the old index after the alias has been switched
78+
if (null !== $oldIndexName) {
79+
$this->deleteIndex($client, $oldIndexName);
8080
}
81+
}
8182

83+
/**
84+
* Builds an ElasticSearch request to rename or create an alias.
85+
*
86+
* @param string|null $aliasedIndex
87+
* @param string $aliasName
88+
* @param string $newIndexName
89+
* @return array
90+
*/
91+
private function buildAliasUpdateRequest($aliasedIndex, $aliasName, $newIndexName)
92+
{
8293
$aliasUpdateRequest = array('actions' => array());
83-
if (count($aliasedIndexes) === 1) {
94+
if (null !== $aliasedIndex) {
8495
// if the alias is set - add an action to remove it
85-
$oldIndexName = $aliasedIndexes[0];
8696
$aliasUpdateRequest['actions'][] = array(
87-
'remove' => array('index' => $oldIndexName, 'alias' => $aliasName),
97+
'remove' => array('index' => $aliasedIndex, 'alias' => $aliasName),
8898
);
8999
}
90100

@@ -93,58 +103,68 @@ public function switchIndexAlias(IndexConfig $indexConfig, Index $index, $force
93103
'add' => array('index' => $newIndexName, 'alias' => $aliasName),
94104
);
95105

96-
try {
97-
$client->request('_aliases', 'POST', $aliasUpdateRequest);
98-
} catch (ExceptionInterface $renameAliasException) {
99-
$additionalError = '';
100-
// if we failed to move the alias, delete the newly built index
101-
try {
102-
$index->delete();
103-
} catch (ExceptionInterface $deleteNewIndexException) {
104-
$additionalError = sprintf(
105-
'Tried to delete newly built index %s, but also failed: %s',
106-
$newIndexName,
107-
$deleteNewIndexException->getMessage()
108-
);
109-
}
106+
return $aliasUpdateRequest;
107+
}
110108

111-
throw new \RuntimeException(
112-
sprintf(
113-
'Failed to updated index alias: %s. %s',
114-
$renameAliasException->getMessage(),
115-
$additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName)
116-
), 0, $renameAliasException
109+
/**
110+
* Cleans up an index when we encounter a failure to rename the alias.
111+
*
112+
* @param Client $client
113+
* @param $indexName
114+
* @param \Exception $renameAliasException
115+
*/
116+
private function cleanupRenameFailure(Client $client, $indexName, \Exception $renameAliasException)
117+
{
118+
$additionalError = '';
119+
try {
120+
$this->deleteIndex($client, $indexName);
121+
} catch (ExceptionInterface $deleteNewIndexException) {
122+
$additionalError = sprintf(
123+
'Tried to delete newly built index %s, but also failed: %s',
124+
$indexName,
125+
$deleteNewIndexException->getMessage()
117126
);
118127
}
119128

120-
// Delete the old index after the alias has been switched
121-
if ($oldIndexName) {
122-
$oldIndex = new Index($client, $oldIndexName);
123-
try {
124-
$oldIndex->delete();
125-
} catch (ExceptionInterface $deleteOldIndexException) {
126-
throw new \RuntimeException(
127-
sprintf(
128-
'Failed to delete old index %s with message: %s',
129-
$oldIndexName,
130-
$deleteOldIndexException->getMessage()
131-
), 0, $deleteOldIndexException
132-
);
133-
}
129+
throw new \RuntimeException(sprintf(
130+
'Failed to updated index alias: %s. %s',
131+
$renameAliasException->getMessage(),
132+
$additionalError ?: sprintf('Newly built index %s was deleted', $indexName)
133+
), 0, $renameAliasException);
134+
}
135+
136+
/**
137+
* Delete an index.
138+
*
139+
* @param Client $client
140+
* @param string $indexName Index name to delete
141+
*/
142+
private function deleteIndex(Client $client, $indexName)
143+
{
144+
try {
145+
$path = sprintf("%s", $indexName);
146+
$client->request($path, Request::DELETE);
147+
} catch (ExceptionInterface $deleteOldIndexException) {
148+
throw new \RuntimeException(sprintf(
149+
'Failed to delete index %s with message: %s',
150+
$indexName,
151+
$deleteOldIndexException->getMessage()
152+
), 0, $deleteOldIndexException);
134153
}
135154
}
136155

137156
/**
138-
* Returns array of indexes which are mapped to given alias.
157+
* Returns the name of a single index that an alias points to or throws
158+
* an exception if there is more than one.
139159
*
140160
* @param Client $client
141161
* @param string $aliasName Alias name
142162
*
143-
* @return array
163+
* @return string|null
144164
*
145165
* @throws AliasIsIndexException
146166
*/
147-
private function getAliasedIndexes(Client $client, $aliasName)
167+
private function getAliasedIndex(Client $client, $aliasName)
148168
{
149169
$aliasesInfo = $client->request('_aliases', 'GET')->getData();
150170
$aliasedIndexes = array();
@@ -163,18 +183,15 @@ private function getAliasedIndexes(Client $client, $aliasName)
163183
}
164184
}
165185

166-
return $aliasedIndexes;
167-
}
186+
if (count($aliasedIndexes) > 1) {
187+
throw new \RuntimeException(sprintf(
188+
'Alias %s is used for multiple indexes: [%s]. Make sure it\'s'.
189+
'either not used or is assigned to one index only',
190+
$aliasName,
191+
implode(', ', $aliasedIndexes)
192+
));
193+
}
168194

169-
/**
170-
* Delete an index.
171-
*
172-
* @param Client $client
173-
* @param string $indexName Index name to delete
174-
*/
175-
private function deleteIndex(Client $client, $indexName)
176-
{
177-
$path = sprintf("%s", $indexName);
178-
$client->request($path, Request::DELETE);
195+
return array_shift($aliasedIndexes);
179196
}
180197
}

0 commit comments

Comments
 (0)