@@ -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