Passed
Push — sheepy/introspection ( 17b395...901708 )
by Simon
08:33 queued 05:46
created

SolrConfigureTask   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Test Coverage

Coverage 82.5%

Importance

Changes 13
Bugs 1 Features 0
Metric Value
wmc 11
eloc 43
c 13
b 1
f 0
dl 0
loc 111
ccs 33
cts 40
cp 0.825
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getStore() 0 9 1
A __construct() 0 3 1
A createConfigForIndex() 0 7 1
A configureIndex() 0 27 5
A run() 0 22 3
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Tasks;
5
6
use Exception;
7
use Firesphere\SolrSearch\Indexes\BaseIndex;
8
use Firesphere\SolrSearch\Interfaces\ConfigStore;
9
use Firesphere\SolrSearch\Services\SolrCoreService;
10
use Firesphere\SolrSearch\Stores\FileConfigStore;
11
use Firesphere\SolrSearch\Stores\PostConfigStore;
12
use Firesphere\SolrSearch\Traits\LoggerTrait;
13
use GuzzleHttp\Exception\RequestException;
14
use ReflectionException;
15
use RuntimeException;
16
use SilverStripe\Control\HTTPRequest;
17
use SilverStripe\Core\Injector\Injector;
18
use SilverStripe\Dev\BuildTask;
19
20
class SolrConfigureTask extends BuildTask
21
{
22
    use LoggerTrait;
23
24
    protected static $storeModes = [
25
        'file' => FileConfigStore::class,
26
        'post' => PostConfigStore::class,
27
//        'webdav' => WebdavConfigStore::class, // @todo
28
    ];
29
    private static $segment = 'SolrConfigureTask';
30
    protected $title = 'Configure Solr cores';
31
    protected $description = 'Create or reload a Solr Core by adding or reloading a configuration.';
32
33 26
    public function __construct()
34
    {
35 26
        parent::__construct();
36 26
    }
37
38
    /**
39
     * Implement this method in the task subclass to
40
     * execute via the TaskRunner
41
     *
42
     * @param HTTPRequest $request
43
     * @return bool|Exception
44
     * @throws ReflectionException
45
     */
46 25
    public function run($request)
47
    {
48 25
        $this->extend('onBeforeSolrConfigureTask', $request);
49
50 25
        $indexes = (new SolrCoreService())->getValidIndexes();
51
52 25
        foreach ($indexes as $index) {
53
            try {
54 25
                $this->configureIndex($index);
55
            } catch (RequestException $error) {
56
                $exception = $error->getResponse()->getBody()->getContents();
57
                $this->getLogger()->error($exception);
58
                $this->getLogger()->error(sprintf('Core loading failed for %s', $index));
59
                // Continue to the next index
60
                continue;
61
            }
62 25
            $this->extend('onAfterConfigureIndex', $index);
63
        }
64
65 25
        $this->extend('onAfterSolrConfigureTask');
66
67 25
        return true;
68
    }
69
70
    /**
71
     * Update the index on the given store
72
     *
73
     * @param string $index
74
     */
75 25
    protected function configureIndex($index): void
76
    {
77
        /** @var BaseIndex $instance */
78 25
        $instance = Injector::inst()->get($index, false);
79
80 25
        $index = $instance->getIndexName();
81
82
        // Then tell Solr to use those config files
83
        /** @var SolrCoreService $service */
84 25
        $service = Injector::inst()->get(SolrCoreService::class);
85
86
        // Assuming a core that doesn't exist doesn't have uptime, as per Solr docs
87
        // And it has a start time.
88
        // You'd have to be pretty darn fast to hit 0 uptime and 0 starttime for an existing core!
89 25
        $status = $service->coreStatus($index);
90 25
        $configStore = $this->createConfigForIndex($instance);
91
        // Default to create
92 25
        $method = 'coreCreate';
93
        // Switch to reload if the core is loaded
94 25
        if ($status && ($status->getUptime() && $status->getStartTime() !== null)) {
95 25
            $method = 'coreReload';
96
        }
97
        try {
98 25
            $service->$method($index, $configStore);
99 25
            $this->getLogger()->info(sprintf('Core %s successfully loaded', $index));
100
        } catch (RequestException $error) {
101
            throw new RuntimeException($error);
102
        }
103 25
    }
104
105
    /**
106
     * @param BaseIndex $instance
107
     * @return ConfigStore
108
     */
109 25
    protected function createConfigForIndex(BaseIndex $instance): ConfigStore
110
    {
111 25
        $storeConfig = SolrCoreService::config()->get('store');
112 25
        $configStore = $this->getStore($storeConfig);
113 25
        $instance->uploadConfig($configStore);
114
115 25
        return $configStore;
116
    }
117
118
    /**
119
     * @param $storeConfig
120
     * @return ConfigStore
121
     */
122 25
    protected function getStore($storeConfig): ConfigStore
123
    {
124 25
        $store = static::$storeModes[$storeConfig['mode']];
125 25
        $configStore = Injector::inst()->create($store, $storeConfig);
126
127
        // Allow changing the configStore if it needs to change to a different store
128 25
        $this->extend('onBeforeConfig', $configStore, $storeConfig);
129
130 25
        return $configStore;
131
    }
132
}
133