55use Psr \Log \LoggerInterface ;
66use Psr \Log \NullLogger ;
77use Elasticsearch \Client ;
8+ use Zumba \ElasticsearchRotator \Common \PrimaryIndexStrategy ;
89
910class IndexRotator
1011{
11- const INDEX_NAME_CONFIG = '.%s_configuration ' ;
12- const TYPE_CONFIGURATION = 'configuration ' ;
1312 const SECONDARY_NAME_ONLY = 0 ;
1413 const SECONDARY_INCLUDE_ID = 1 ;
15- const PRIMARY_ID = 'primary ' ;
1614 const RETRY_TIME_COPY = 500000 ;
1715 const MAX_RETRY_COUNT = 5 ;
16+ const STRATEGY_CONFIGURATION = 'Zumba\ElasticsearchRotator\Strategy\ConfigurationStrategy ' ;
17+ const STRATEGY_ALIAS = 'Zumba\ElasticsearchRotator\Strategy\AliasStrategy ' ;
18+ const DEFAULT_PRIMARY_INDEX_STRATEGY = self ::STRATEGY_CONFIGURATION ;
1819
1920 /**
2021 * Elasticsearch client instance.
@@ -24,18 +25,18 @@ class IndexRotator
2425 private $ engine ;
2526
2627 /**
27- * Prefix identifier for this index.
28+ * Configuration index name for this index.
2829 *
29- * @var string
30+ * @var \Zumba\ElasticsearchRotator\ConfigurationIndex
3031 */
31- private $ prefix ;
32+ private $ configurationIndex ;
3233
3334 /**
34- * Configuration index name for this index.
35+ * Strategy to employ when working on primary index.
3536 *
36- * @var string
37+ * @var \Zumba\ElasticsearchRotator\Common\PrimaryIndexStrategy
3738 */
38- private $ configurationIndexName ;
39+ private $ primaryIndexStrategy ;
3940
4041 /**
4142 * Mapping for configuration index.
@@ -62,13 +63,31 @@ class IndexRotator
6263 public function __construct (\Elasticsearch \Client $ engine , $ prefix , LoggerInterface $ logger = null )
6364 {
6465 $ this ->engine = $ engine ;
65- $ this ->prefix = $ prefix ;
66- if ($ logger !== null ) {
67- $ this ->logger = $ logger ;
68- } else {
69- $ this ->logger = new NullLogger ();
70- }
71- $ this ->configurationIndexName = sprintf (static ::INDEX_NAME_CONFIG , $ this ->prefix );
66+ $ this ->logger = $ logger ?: new NullLogger ();
67+ $ this ->configurationIndex = new ConfigurationIndex ($ this ->engine , $ this ->logger , $ prefix );
68+ $ this ->setPrimaryIndexStrategy ($ this ->strategyFactory (static ::DEFAULT_PRIMARY_INDEX_STRATEGY , [
69+ 'configuration_index ' => $ this ->configurationIndex
70+ ]));
71+ }
72+
73+ /**
74+ * Instantiate a specific strategy.
75+ *
76+ * @param string $strategyClass Fully qualified class name for a strategy.
77+ * @param array $options Options specific to the strategy
78+ * @return \Zumba\ElasticsearchRotator\Common\PrimaryIndexStrategy
79+ */
80+ public function strategyFactory ($ strategyClass , array $ options = []) {
81+ return new $ strategyClass ($ this ->engine , $ this ->logger , $ options );
82+ }
83+
84+ /**
85+ * Set the primary index strategy.
86+ *
87+ * @param \Zumba\ElasticsearchRotator\Common\PrimaryIndexStrategy $strategy
88+ */
89+ public function setPrimaryIndexStrategy (PrimaryIndexStrategy $ strategy ) {
90+ $ this ->primaryIndexStrategy = $ strategy ;
7291 }
7392
7493 /**
@@ -79,23 +98,8 @@ public function __construct(\Elasticsearch\Client $engine, $prefix, LoggerInterf
7998 */
8099 public function getPrimaryIndex ()
81100 {
82- if (!$ this ->engine ->indices ()->exists (['index ' => $ this ->configurationIndexName ])) {
83- $ this ->logger ->error ('Primary index configuration index not available. ' );
84- throw new Exception \MissingPrimaryIndex ('Primary index configuration index not available. ' );
85- }
86- $ primaryPayload = [
87- 'index ' => $ this ->configurationIndexName ,
88- 'type ' => static ::TYPE_CONFIGURATION ,
89- 'id ' => static ::PRIMARY_ID ,
90- 'preference ' => '_primary '
91- ];
92- try {
93- $ primary = $ this ->engine ->get ($ primaryPayload );
94- } catch (\Elasticsearch \Common \Exceptions \Missing404Exception $ e ) {
95- $ this ->logger ->error ('Primary index does not exist. ' );
96- throw new Exception \MissingPrimaryIndex ('Primary index not available. ' );
97- }
98- return $ primary ['_source ' ]['name ' ];
101+ return $ this ->primaryIndexStrategy ->getPrimaryIndex ();
102+
99103 }
100104
101105 /**
@@ -106,19 +110,7 @@ public function getPrimaryIndex()
106110 */
107111 public function setPrimaryIndex ($ name )
108112 {
109- if (!$ this ->engine ->indices ()->exists (['index ' => $ this ->configurationIndexName ])) {
110- $ this ->createCurrentIndexConfiguration ();
111- }
112- $ this ->engine ->index ([
113- 'index ' => $ this ->configurationIndexName ,
114- 'type ' => static ::TYPE_CONFIGURATION ,
115- 'id ' => static ::PRIMARY_ID ,
116- 'body ' => [
117- 'name ' => $ name ,
118- 'timestamp ' => time ()
119- ]
120- ]);
121- $ this ->logger ->debug ('Primary index set. ' , compact ('name ' ));
113+ $ this ->primaryIndexStrategy ->setPrimaryIndex ($ name );
122114 }
123115
124116 /**
@@ -130,9 +122,7 @@ public function setPrimaryIndex($name)
130122 */
131123 public function copyPrimaryIndexToSecondary ($ retryCount = 0 )
132124 {
133- if (!$ this ->engine ->indices ()->exists (['index ' => $ this ->configurationIndexName ])) {
134- $ this ->createCurrentIndexConfiguration ();
135- }
125+ $ this ->configurationIndex ->createCurrentIndexConfiguration ();
136126 try {
137127 $ primaryName = $ this ->getPrimaryIndex ();
138128 } catch (\Elasticsearch \Common \Exceptions \ServerErrorResponseException $ e ) {
@@ -144,8 +134,8 @@ public function copyPrimaryIndexToSecondary($retryCount = 0)
144134 return $ this ->copyPrimaryIndexToSecondary ($ retryCount ++);
145135 }
146136 $ id = $ this ->engine ->index ([
147- 'index ' => $ this ->configurationIndexName ,
148- 'type ' => static ::TYPE_CONFIGURATION ,
137+ 'index ' => ( string ) $ this ->configurationIndex ,
138+ 'type ' => ConfigurationIndex ::TYPE_CONFIGURATION ,
149139 'body ' => [
150140 'name ' => $ primaryName ,
151141 'timestamp ' => time ()
@@ -170,14 +160,14 @@ public function getSecondaryIndices(\DateTime $olderThan = null, $disposition =
170160 $ olderThan = new \DateTime ();
171161 }
172162 $ params = [
173- 'index ' => $ this ->configurationIndexName ,
174- 'type ' => static ::TYPE_CONFIGURATION ,
163+ 'index ' => ( string ) $ this ->configurationIndex ,
164+ 'type ' => ConfigurationIndex ::TYPE_CONFIGURATION ,
175165 'body ' => [
176166 'query ' => [
177167 'bool ' => [
178168 'must_not ' => [
179169 'term ' => [
180- '_id ' => static ::PRIMARY_ID
170+ '_id ' => ConfigurationIndex ::PRIMARY_ID
181171 ]
182172 ],
183173 'filter ' => [
@@ -231,51 +221,20 @@ public function deleteSecondaryIndices(\DateTime $olderThan = null)
231221 if ($ this ->engine ->indices ()->exists (['index ' => $ indexToDelete ['index ' ]])) {
232222 $ results [$ indexToDelete ['index ' ]] = [
233223 'index ' => $ this ->engine ->indices ()->delete (['index ' => $ indexToDelete ['index ' ]]),
234- 'config ' => $ this ->deleteConfigurationEntry ($ indexToDelete ['configuration_id ' ])
224+ 'config ' => $ this ->configurationIndex -> deleteConfigurationEntry ($ indexToDelete ['configuration_id ' ])
235225 ];
236226 $ this ->logger ->debug ('Deleted secondary index. ' , compact ('indexToDelete ' ));
237227 } else {
238228 $ results [$ indexToDelete ] = [
239229 'index ' => null ,
240- 'config ' => $ this ->deleteConfigurationEntry ($ indexToDelete ['configuration_id ' ])
230+ 'config ' => $ this ->configurationIndex -> deleteConfigurationEntry ($ indexToDelete ['configuration_id ' ])
241231 ];
242232 $ this ->logger ->debug ('Index not found to delete. ' , compact ('indexToDelete ' ));
243233 }
244234 }
245235 return $ results ;
246236 }
247237
248- /**
249- * Delete an entry from the configuration index.
250- *
251- * @param string $id
252- * @return array
253- */
254- private function deleteConfigurationEntry ($ id )
255- {
256- return $ this ->engine ->delete ([
257- 'index ' => $ this ->configurationIndexName ,
258- 'type ' => static ::TYPE_CONFIGURATION ,
259- 'id ' => $ id
260- ]);
261- }
262-
263- /**
264- * Create the index needed to store the primary index name.
265- *
266- * @return void
267- */
268- private function createCurrentIndexConfiguration ()
269- {
270- $ this ->engine ->indices ()->create ([
271- 'index ' => $ this ->configurationIndexName ,
272- 'body ' => static ::$ elasticSearchConfigurationMapping
273- ]);
274- $ this ->logger ->debug ('Configuration index created. ' , [
275- 'index ' => $ this ->configurationIndexName
276- ]);
277- }
278-
279238 /**
280239 * Determines if the combined filter in query DSL is supported.
281240 *
0 commit comments