Passed
Push — feature/Logging ( 0ade54 )
by Simon
04:18
created

SolrConfigureTask   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 80.48%

Importance

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