Completed
Pull Request — develop (#115)
by
unknown
04:16
created

IndexCommand::getErrors()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 29
rs 9.7
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php namespace Nord\Lumen\Elasticsearch\Console;
2
3
use Nord\Lumen\Elasticsearch\Documents\Bulk\BulkAction;
4
use Nord\Lumen\Elasticsearch\Documents\Bulk\BulkQuery;
5
6
abstract class IndexCommand extends AbstractCommand
7
{
8
9
    /**
10
     * The number of items to process before updating the progress bar
11
     */
12
    const PROGRESS_BAR_REDRAW_FREQUENCY = 50;
13
14
    /**
15
     * @return array
16
     */
17
    abstract public function getData();
18
19
    /**
20
     * @return string
21
     */
22
    abstract public function getIndex();
23
24
    /**
25
     * @return string
26
     */
27
    abstract public function getType();
28
29
    /**
30
     * @param mixed $item
31
     *
32
     * @return array
33
     */
34
    abstract public function getItemBody($item);
35
36
    /**
37
     * @param mixed $item
38
     *
39
     * @return string
40
     */
41
    abstract public function getItemId($item);
42
43
    /**
44
     * @param mixed $item
45
     *
46
     * @return string
47
     */
48
    abstract public function getItemParent($item);
49
50
    /**
51
     * @inheritdoc
52
     */
53
    public function handle()
54
    {
55
        $this->info(sprintf('Indexing data of type "%s" into "%s"', $this->getType(), $this->getIndex()));
56
57
        $data = $this->getData();
58
59
        $bar = $this->output->createProgressBar($this->getCount());
60
        $bar->setRedrawFrequency($this->getProgressBarRedrawFrequency());
61
62
        $bulkQuery = new BulkQuery($this->getBulkSize());
63
        $responses = [];
64
65
        foreach ($data as $item) {
66
            $action = new BulkAction();
67
68
            $meta = [
69
                '_index' => $this->getIndex(),
70
                '_type'  => $this->getType(),
71
                '_id'    => $this->getItemId($item),
72
            ];
73
74
            if (($parent = $this->getItemParent($item)) !== null) {
75
                $meta['_parent'] = $parent;
76
            }
77
78
            $action->setAction(BulkAction::ACTION_INDEX, $meta)
79
                   ->setBody($this->getItemBody($item));
80
81
            $bulkQuery->addAction($action);
82
83
            if ($bulkQuery->isReady()) {
84
                $responses[] = $this->elasticsearchService->bulk($bulkQuery->toArray());
85
                $bulkQuery->reset();
86
            }
87
88
            $bar->advance();
89
        }
90
91
        if ($bulkQuery->hasItems()) {
92
            $responses[] = $this->elasticsearchService->bulk($bulkQuery->toArray());
93
        }
94
95
        $bar->finish();
96
97
        $errors = $this->getErrors($responses);
98
        if($errors) {
99
            $this->info("\n");
100
            foreach($errors as $error) {
101
                $this->error($error);
102
            }
103
        }
104
105
        $this->info("\nDone!");
106
107
        return 0;
108
    }
109
110
    /**
111
     * @return int the bulk size (for bulk indexing)
112
     */
113
    protected function getBulkSize()
114
    {
115
        return BulkQuery::BULK_SIZE_DEFAULT;
116
    }
117
118
    /**
119
     * @return int the progress bar redraw frequency
120
     */
121
    protected function getProgressBarRedrawFrequency()
122
    {
123
        return self::PROGRESS_BAR_REDRAW_FREQUENCY;
124
    }
125
126
    /**
127
     * Get the total count.
128
     *
129
     * @return int
130
     */
131
    protected function getCount()
132
    {
133
        return count($this->getData());
134
    }
135
136
    /**
137
     * @param array $responses
138
     * @return array
139
     */
140
    protected function getErrors($responses) 
141
    {
142
        $errors = [];
143
        foreach($responses as $type => $response) {
144
145
            $items = array_get($response, 'items', []);
146
            foreach($items as $item) {
147
148
                $item = array_first($item);
149
150
                if(!array_has($item, 'error')) {
151
                    continue;
152
                }
153
154
                $index = array_get($item, '_index');
155
                $type = array_get($item, '_type');
156
                $id = array_get($item, '_id');
157
158
                $errorType = array_get($item, 'error.type');
159
                $errorReason = array_get($item, 'error.reason');
160
161
                $causeType = array_get($item, 'error.caused_by.type');
162
                $causeReason = array_get($item, 'error.caused_by.reason');
163
164
                $errors[] = sprintf('Error "%s" reason "%s". Cause "%s" reason "%s". Index "%s", type "%s", id "%s"', 
165
                    $errorType, $errorReason, $causeType, $causeReason, $index, $type, $id);
166
            }
167
        }
168
        return $errors;
169
    }
170
}
171