Passed
Push — hans/addAllFields ( 017bc8...d90266 )
by Simon
08:48 queued 06:39
created

SolrConfigureTask::run()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.2098

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 14
c 5
b 0
f 0
dl 0
loc 24
ccs 10
cts 14
cp 0.7143
rs 9.7998
cc 3
nc 3
nop 1
crap 3.2098
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Tasks;
5
6
use Exception;
7
use Firesphere\SolrSearch\Helpers\SolrLogger;
8
use Firesphere\SolrSearch\Indexes\BaseIndex;
9
use Firesphere\SolrSearch\Interfaces\ConfigStore;
10
use Firesphere\SolrSearch\Services\SolrCoreService;
11
use Firesphere\SolrSearch\Stores\FileConfigStore;
12
use Firesphere\SolrSearch\Stores\PostConfigStore;
13
use Firesphere\SolrSearch\Traits\LoggerTrait;
14
use GuzzleHttp\Exception\GuzzleException;
15
use ReflectionException;
16
use RuntimeException;
17
use SilverStripe\Control\HTTPRequest;
18
use SilverStripe\Core\Injector\Injector;
19
use SilverStripe\Dev\BuildTask;
20
use SilverStripe\Dev\Debug;
21
use SilverStripe\ORM\ValidationException;
22
23
/**
24
 * Class SolrConfigureTask
25
 * @package Firesphere\SolrSearch\Tasks
26
 */
27
class SolrConfigureTask extends BuildTask
28
{
29
    use LoggerTrait;
30
31
    protected static $storeModes = [
32
        'file' => FileConfigStore::class,
33
        'post' => PostConfigStore::class,
34
//        'webdav' => WebdavConfigStore::class,
35
    ];
36
    private static $segment = 'SolrConfigureTask';
37
    protected $title = 'Configure Solr cores';
38
    protected $description = 'Create or reload a Solr Core by adding or reloading a configuration.';
39
40 30
    public function __construct()
41
    {
42 30
        parent::__construct();
43 30
    }
44
45
    /**
46
     * Implement this method in the task subclass to
47
     * execute via the TaskRunner
48
     *
49
     * @param HTTPRequest $request
50
     * @return bool|Exception
51
     * @throws ReflectionException
52
     * @throws ValidationException
53
     * @throws GuzzleException
54
     */
55 29
    public function run($request)
56
    {
57 29
        $this->extend('onBeforeSolrConfigureTask', $request);
58
59 29
        $indexes = (new SolrCoreService())->getValidIndexes();
60
61 29
        foreach ($indexes as $index) {
62
            try {
63 29
                $this->configureIndex($index);
64
            } catch (Exception $error) {
65
                $this->getLogger()->error(sprintf('Core loading failed for %s', $index));
66
                Debug::dump($error); // in browser mode, it might not always show
67
                // Continue to the next index
68
                continue;
69
            }
70 29
            $this->extend('onAfterConfigureIndex', $index);
71
        }
72
73 29
        $this->extend('onAfterSolrConfigureTask');
74
        // Grab the latest logs
75 29
        $solrLogger = new SolrLogger();
76 29
        $solrLogger->saveSolrLog('Config');
77
78 29
        return true;
79
    }
80
81
    /**
82
     * Update the index on the given store
83
     *
84
     * @param string $index
85
     * @throws ValidationException
86
     * @throws GuzzleException
87
     */
88 29
    protected function configureIndex($index): void
89
    {
90
        /** @var BaseIndex $instance */
91 29
        $instance = Injector::inst()->get($index, false);
92
93 29
        $index = $instance->getIndexName();
94
95
        // Then tell Solr to use those config files
96
        /** @var SolrCoreService $service */
97 29
        $service = Injector::inst()->get(SolrCoreService::class);
98
99
        // Assuming a core that doesn't exist doesn't have uptime, as per Solr docs
100
        // And it has a start time.
101
        // You'd have to be pretty darn fast to hit 0 uptime and 0 starttime for an existing core!
102 29
        $status = $service->coreStatus($index);
103 29
        $configStore = $this->createConfigForIndex($instance);
104
        // Default to create
105 29
        $method = 'coreCreate';
106
        // Switch to reload if the core is loaded
107 29
        if ($status && ($status->getUptime() && $status->getStartTime() !== null)) {
108 29
            $method = 'coreReload';
109
        }
110
        try {
111 29
            $service->$method($index, $configStore);
112 29
            $this->getLogger()->info(sprintf('Core %s successfully loaded', $index));
113
        } catch (Exception $error) {
114
            $this->logException($index, $error);
115
            throw new RuntimeException($error);
116
        }
117 29
    }
118
119
    /**
120
     * @param BaseIndex $instance
121
     * @return ConfigStore
122
     */
123 29
    protected function createConfigForIndex(BaseIndex $instance): ConfigStore
124
    {
125 29
        $storeConfig = SolrCoreService::config()->get('store');
126 29
        $configStore = $this->getStore($storeConfig);
127 29
        $instance->uploadConfig($configStore);
128
129 29
        return $configStore;
130
    }
131
132
    /**
133
     * @param $storeConfig
134
     * @return ConfigStore
135
     */
136 29
    protected function getStore($storeConfig): ConfigStore
137
    {
138 29
        $store = static::$storeModes[$storeConfig['mode']];
139 29
        $configStore = Injector::inst()->create($store, $storeConfig);
140
141
        // Allow changing the configStore if it needs to change to a different store
142 29
        $this->extend('onBeforeConfig', $configStore, $storeConfig);
143
144 29
        return $configStore;
145
    }
146
147
    /**
148
     * @param $index
149
     * @param Exception $error
150
     * @throws GuzzleException
151
     * @throws ValidationException
152
     */
153
    private function logException($index, Exception $error): void
154
    {
155
        $this->getLogger()->error($error);
156
        $msg = sprintf(
157
            'Error loading core %s,' . PHP_EOL .
158
            'Please log in to the CMS to find out more about Configuration errors' . PHP_EOL,
159
            $index
160
        );
161
        SolrLogger::logMessage('ERROR', $msg, $index);
162
    }
163
}
164