Completed
Push — master ( 1cb637...fff2ec )
by X
9s
created

Couchbase::get()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Couchbase Adapter for ackintosh/ganesha
4
 */
5
namespace GaneshaPlugin\Adapter;
6
7
use Ackintosh\Ganesha;
8
use Ackintosh\Ganesha\Exception\StorageException;
9
use Ackintosh\Ganesha\Configuration;
10
use Ackintosh\Ganesha\Storage\AdapterInterface;
11
use Ackintosh\Ganesha\Storage\Adapter\TumblingTimeWindowInterface;
12
use Couchbase\Bucket;
13
use Couchbase\Exception as CBException;
14
15
/**
16
 * Adapter class using Couchbase
17
 */
18
class Couchbase implements AdapterInterface, TumblingTimeWindowInterface
19
{
20
    /**
21
     * @var \Couchbase\Bucket $bucket Couchbase bucket to manage data
22
     */
23
    private $bucket;
24
25
    /**
26
     * @var \Ackintosh\Ganesha\Configuration $configuration circuit breaker configuration
27
     */
28
    private $configuration;
29
30
    /**
31
     * constructor
32
     *
33
     * @param \Couchbase\Bucket $bucket Couchbase bucket to manage data
34
     */
35 1
    public function __construct(Bucket $bucket)
36
    {
37 1
        $this->bucket = $bucket;
38
    }
39
40
    /**
41
     * set circuit breaker configuration
42
     *
43
     * @param \Ackintosh\Ganesha\Configuration $configuration circuit breaker configuration
44
     * @return void
45
     */
46 1
    public function setConfiguration(Configuration $configuration)
47
    {
48 1
        $this->configuration = $configuration;
49
    }
50
51
    /**
52
     * load success / failure / rejection count
53
     *
54
     * @param  string $service name of the service
55
     * @return int
56
     * @throws \Ackintosh\Ganesha\Exception\StorageException
57
     */
58 3
    public function load($service)
59
    {
60 3
        return $this->get($service, 0);
61
    }
62
63
    /**
64
     * save success / failure / rejection count
65
     *
66
     * @param  string $service name of the service
67
     * @param  int    $count   success / failure / rejection count of the service
68
     * @return void
69
     * @throws \Ackintosh\Ganesha\Exception\StorageException
70
     */
71 2
    public function save($service, $count)
72
    {
73 2
        $this->upsert($service, $count);
74
    }
75
76
    /**
77
     * increment success / failure / rejection count
78
     *
79
     * @param  string $service name of the service
80
     * @return void
81
     * @throws \Ackintosh\Ganesha\Exception\StorageException
82
     */
83 2
    public function increment($service)
84
    {
85 2
        $this->counter($service, 1);
86
    }
87
88
    /**
89
     * decrement failure count
90
     *
91
     * If the operation would decrease the value below 0, the new value must be 0.
92
     *
93
     * @param  string $service name of the service
94
     * @return void
95
     * @throws \Ackintosh\Ganesha\Exception\StorageException
96
     */
97 2
    public function decrement($service)
98
    {
99 2
        $this->counter($service, -1);
100
    }
101
102
    /**
103
     * sets last failure time
104
     *
105
     * @param  string $service         name of the service
106
     * @param  int    $lastFailureTime last failure time (unix time)
107
     * @return void
108
     * @throws \Ackintosh\Ganesha\Exception\StorageException
109
     */
110 2
    public function saveLastFailureTime($service, $lastFailureTime)
111
    {
112 2
        $this->upsert($service, $lastFailureTime);
113
    }
114
115
    /**
116
     * returns last failure time
117
     *
118
     * @param string $service name of the service
119
     * @return int | null
120
     * @throws \Ackintosh\Ganesha\Exception\StorageException
121
     */
122 3
    public function loadLastFailureTime($service)
123
    {
124 3
        return $this->get($service, null);
125
    }
126
127
    /**
128
     * sets status
129
     *
130
     * @param  string $service name of the service
131
     * @param  int    $status  status of the service
132
     * @return void
133
     * @throws \Ackintosh\Ganesha\Exception\StorageException
134
     */
135 2
    public function saveStatus($service, $status)
136
    {
137 2
        $this->upsert($service, $status);
138
    }
139
140
    /**
141
     * returns status
142
     *
143
     * @param  string $service name of the service
144
     * @return int
145
     * @throws \Ackintosh\Ganesha\Exception\StorageException
146
     */
147 3
    public function loadStatus($service)
148
    {
149 3
        return $this->get($service, Ganesha::STATUS_CALMED_DOWN);
150
    }
151
152
    /**
153
     * resets all counts
154
     *
155
     * @return void
156
     * @throws \Ackintosh\Ganesha\Exception\StorageException
157
     */
158 1
    public function reset()
159
    {
160 1
        throw new \RuntimeException('not implemented');
161
    }
162
163
    /**
164
     * return option parameters for Couchbase operation
165
     *
166
     * @param array $additional additional option
167
     * @return array
168
     */
169 10
    private function getOptions(array $additional = [])
170
    {
171 10
        $expiry = isset($this->configuration['timeWindow']) ?
172 10
                $this->configuration['timeWindow'] * 2 : // current + previous
173 10
                0;
174
        $initial = [
175 10
            'expiry' => $expiry,
176
        ];
177 10
        return array_merge($initial, $additional);
178
    }
179
180
    /**
181
     * get data from couchbase bucket
182
     *
183
     * @param string $key     key of the document
184
     * @param mixed  $default default value for missing document
185
     * @return mixed
186
     * @throws \Ackintosh\Ganesha\Exception\StorageException
187
     */
188 11
    private function get($key, $default)
189
    {
190
        try {
191 11
            $doc = $this->bucket->get($key, []);
192 6
        } catch (CBException $e) {
193 6
            if ($e->getCode() === COUCHBASE_KEY_ENOENT) {
194 3
                return $default;
195
            }
196 3
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
197
        }
198 5
        return $doc->value;
199
    }
200
201
    /**
202
     * update or insert value for given key
203
     *
204
     * @param string $key   id of the document
205
     * @param mixed  $value value of the document
206
     * @return void
207
     * @throws \Ackintosh\Ganesha\Exception\StorageException
208
     */
209 7
    private function upsert($key, $value)
210
    {
211
        try {
212 7
            $this->bucket->upsert($key, $value, $this->getOptions());
213 3
        } catch (CBException $e) {
214 3
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
215
        }
216
    }
217
218
    /**
219
     * increment / decrement counter for given key
220
     *
221
     * @param string $key   key of the counter
222
     * @param int    $delta increment / decrement delta
223
     * @return void
224
     * @throws \Ackintosh\Ganesha\Exception\StorageException
225
     */
226 4
    private function counter($key, $delta)
227
    {
228
        try {
229 4
            $this->bucket->counter($key, $delta, $this->getOptions(['initial' => 0]));
230 2
        } catch (\Couchbase\Exception $e) {
231 2
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
232
        }
233
    }
234
}
235