1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\NotFoundException;
6use Elastica\Exception\ResponseException;
7use Elasticsearch\Endpoints\Snapshot\Restore;
8
9/**
10 * Class Snapshot.
11 *
12 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html
13 */
14class Snapshot
15{
16    /**
17     * @var Client
18     */
19    protected $_client;
20
21    /**
22     * @param Client $client
23     */
24    public function __construct(Client $client)
25    {
26        $this->_client = $client;
27    }
28
29    /**
30     * Register a snapshot repository.
31     *
32     * @param string $name     the name of the repository
33     * @param string $type     the repository type ("fs" for file system)
34     * @param array  $settings Additional repository settings. If type "fs" is used, the "location" setting must be provided.
35     *
36     * @return Response
37     */
38    public function registerRepository($name, $type, $settings = [])
39    {
40        $data = [
41            'type' => $type,
42            'settings' => $settings,
43        ];
44
45        return $this->request($name, Request::PUT, $data);
46    }
47
48    /**
49     * Retrieve a repository record by name.
50     *
51     * @param string $name the name of the desired repository
52     *
53     * @throws Exception\ResponseException
54     * @throws Exception\NotFoundException
55     *
56     * @return array
57     */
58    public function getRepository($name)
59    {
60        try {
61            $response = $this->request($name);
62        } catch (ResponseException $e) {
63            if (404 == $e->getResponse()->getStatus()) {
64                throw new NotFoundException("Repository '".$name."' does not exist.");
65            }
66            throw $e;
67        }
68        $data = $response->getData();
69
70        return $data[$name];
71    }
72
73    /**
74     * Retrieve all repository records.
75     *
76     * @return array
77     */
78    public function getAllRepositories()
79    {
80        return $this->request('_all')->getData();
81    }
82
83    /**
84     * Create a new snapshot.
85     *
86     * @param string $repository        the name of the repository in which this snapshot should be stored
87     * @param string $name              the name of this snapshot
88     * @param array  $options           optional settings for this snapshot
89     * @param bool   $waitForCompletion if true, the request will not return until the snapshot operation is complete
90     *
91     * @return Response
92     */
93    public function createSnapshot($repository, $name, $options = [], $waitForCompletion = false)
94    {
95        return $this->request($repository.'/'.$name, Request::PUT, $options, ['wait_for_completion' => $waitForCompletion]);
96    }
97
98    /**
99     * Retrieve data regarding a specific snapshot.
100     *
101     * @param string $repository the name of the repository from which to retrieve the snapshot
102     * @param string $name       the name of the desired snapshot
103     *
104     * @throws Exception\ResponseException
105     * @throws Exception\NotFoundException
106     *
107     * @return array
108     */
109    public function getSnapshot($repository, $name)
110    {
111        try {
112            $response = $this->request($repository.'/'.$name);
113        } catch (ResponseException $e) {
114            if (404 == $e->getResponse()->getStatus()) {
115                throw new NotFoundException("Snapshot '".$name."' does not exist in repository '".$repository."'.");
116            }
117            throw $e;
118        }
119        $data = $response->getData();
120
121        return $data['snapshots'][0];
122    }
123
124    /**
125     * Retrieve data regarding all snapshots in the given repository.
126     *
127     * @param string $repository the repository name
128     *
129     * @return array
130     */
131    public function getAllSnapshots($repository)
132    {
133        return $this->request($repository.'/_all')->getData();
134    }
135
136    /**
137     * Delete a snapshot.
138     *
139     * @param string $repository the repository in which the snapshot resides
140     * @param string $name       the name of the snapshot to be deleted
141     *
142     * @return Response
143     */
144    public function deleteSnapshot($repository, $name)
145    {
146        return $this->request($repository.'/'.$name, Request::DELETE);
147    }
148
149    /**
150     * Restore a snapshot.
151     *
152     * @param string $repository        the name of the repository
153     * @param string $name              the name of the snapshot
154     * @param array  $options           options for the restore operation
155     * @param bool   $waitForCompletion if true, the request will not return until the restore operation is complete
156     *
157     * @return Response
158     */
159    public function restoreSnapshot($repository, $name, $options = [], $waitForCompletion = false)
160    {
161        $endpoint = new Restore();
162        $endpoint->setRepository($repository);
163        $endpoint->setSnapshot($name);
164        $endpoint->setBody($options);
165        $endpoint->setParams(['wait_for_completion' => $waitForCompletion]);
166
167        return $this->_client->requestEndpoint($endpoint);
168    }
169
170    /**
171     * Perform a snapshot request.
172     *
173     * @param string $path   the URL
174     * @param string $method the HTTP method
175     * @param array  $data   request body data
176     * @param array  $query  query string parameters
177     *
178     * @return Response
179     */
180    public function request($path, $method = Request::GET, $data = [], array $query = [])
181    {
182        return $this->_client->request('_snapshot/'.$path, $method, $data, $query);
183    }
184}
185