blob: cfa62f5b9f99682ec5d9946825e807a2283f8ed5 [file] [log] [blame]
Patrick Ventureef3aead2018-09-12 08:53:29 -07001#pragma once
2
3#include "blobs.hpp"
4
5#include <ctime>
6#include <memory>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11namespace blobs
12{
13
14struct SessionInfo
15{
16 SessionInfo() = default;
17 SessionInfo(const std::string& path, GenericBlobInterface* handler,
18 uint16_t flags) :
19 blobId(path),
20 handler(handler), flags(flags)
21 {
22 }
23 ~SessionInfo() = default;
24
25 std::string blobId;
26 GenericBlobInterface* handler;
27 uint16_t flags;
28};
29
30class ManagerInterface
31{
32 public:
33 virtual ~ManagerInterface() = default;
34
35 virtual bool
36 registerHandler(std::unique_ptr<GenericBlobInterface> handler) = 0;
37
38 virtual uint32_t buildBlobList() = 0;
39
40 virtual std::string getBlobId(uint32_t index) = 0;
41
42 virtual bool open(uint16_t flags, const std::string& path,
43 uint16_t* session) = 0;
44
45 virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0;
46
47 virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0;
48
49 virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0;
50
51 virtual bool close(uint16_t session) = 0;
52
53 virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset,
54 uint32_t requestedSize) = 0;
55
56 virtual bool write(uint16_t session, uint32_t offset,
57 const std::vector<uint8_t>& data) = 0;
58
59 virtual bool deleteBlob(const std::string& path) = 0;
60};
61
62/**
63 * Blob Manager used to store handlers and sessions.
64 */
65class BlobManager : public ManagerInterface
66{
67 public:
68 BlobManager()
69 {
70 next = static_cast<uint16_t>(std::time(nullptr));
71 };
72
73 ~BlobManager() = default;
74 /* delete copy constructor & assignment operator, only support move
75 * operations.
76 */
77 BlobManager(const BlobManager&) = delete;
78 BlobManager& operator=(const BlobManager&) = delete;
79 BlobManager(BlobManager&&) = default;
80 BlobManager& operator=(BlobManager&&) = default;
81
82 /**
83 * Register a handler. We own the pointer.
84 *
85 * @param[in] handler - a pointer to a blob handler.
86 * @return bool - true if registered.
87 */
88 bool
89 registerHandler(std::unique_ptr<GenericBlobInterface> handler) override;
90
91 /**
92 * Builds the blobId list for enumeration.
93 *
94 * @return lowest value returned is 0, otherwise the number of
95 * blobIds.
96 */
97 uint32_t buildBlobList() override;
98
99 /**
100 * Grabs the blobId for the indexed blobId.
101 *
102 * @param[in] index - the index into the blobId cache.
103 * @return string - the blobId or empty string on failure.
104 */
105 std::string getBlobId(uint32_t index) override;
106
107 /**
108 * Attempts to open the file specified and associates with a session.
109 *
110 * @param[in] flags - the flags to pass to open.
111 * @param[in] path - the file path to open.
112 * @param[in,out] session - pointer to store the session on success.
113 * @return bool - true if able to open.
114 */
115 bool open(uint16_t flags, const std::string& path,
116 uint16_t* session) override;
117
118 /**
119 * Attempts to retrieve a BlobMeta for the specified path.
120 *
121 * @param[in] path - the file path for stat().
122 * @param[in,out] meta - a pointer to store the metadata.
123 * @return bool - true if able to retrieve the information.
124 */
125 bool stat(const std::string& path, struct BlobMeta* meta) override;
126
127 /**
128 * Attempts to retrieve a BlobMeta for a given session.
129 *
130 * @param[in] session - the session for this command.
131 * @param[in,out] meta - a pointer to store the metadata.
132 * @return bool - true if able to retrieve the information.
133 */
134 bool stat(uint16_t session, struct BlobMeta* meta) override;
135
136 /**
137 * Attempt to commit a blob for a given session.
138 *
139 * @param[in] session - the session for this command.
140 * @param[in] data - an optional commit blob.
141 * @return bool - true if the commit succeeds.
142 */
143 bool commit(uint16_t session, const std::vector<uint8_t>& data) override;
144
145 /**
146 * Attempt to close a session. If the handler returns a failure
147 * in closing, the session is kept open.
148 *
149 * @param[in] session - the session for this command.
150 * @return bool - true if the session was closed.
151 */
152 bool close(uint16_t session) override;
153
154 /**
155 * Attempt to read bytes from the blob. If there's a failure, such as
156 * an invalid offset it'll just return 0 bytes.
157 *
158 * @param[in] session - the session for this command.
159 * @param[in] offset - the offset from which to read.
160 * @param[in] requestedSize - the number of bytes to try and read.
161 * @return the bytes read.
162 */
163 std::vector<uint8_t> read(uint16_t session, uint32_t offset,
164 uint32_t requestedSize) override;
165
166 /**
167 * Attempt to write to a blob. The manager does not track whether
168 * the session opened the file for writing.
169 *
170 * @param[in] session - the session for this command.
171 * @param[in] offset - the offset into the blob to write.
172 * @param[in] data - the bytes to write to the blob.
173 * @return bool - true if the write succeeded.
174 */
175 bool write(uint16_t session, uint32_t offset,
176 const std::vector<uint8_t>& data) override;
177
178 /**
179 * Attempt to delete a blobId. This method will just call the
180 * handler, which will return failure if the blob doesn't support
181 * deletion. This command will also fail if there are any open
182 * sessions against the specific blob.
183 *
184 * In the case where they specify a folder, such as /blob/skm where
185 * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager
186 * may see there are on open sessions to that specific path and will
187 * call the handler. In this case, the handler is responsible for
188 * handling any checks or logic.
189 *
190 * @param[in] path - the blobId path.
191 * @return bool - true if delete was successful.
192 */
193 bool deleteBlob(const std::string& path) override;
194
195 /**
196 * Attempts to return a valid unique session id.
197 *
198 * @param[in,out] - pointer to the session.
199 * @return bool - true if able to allocate.
200 */
201 bool getSession(uint16_t* session);
202
203 /**
204 * Given a file path will return first handler to answer that it owns
205 * it.
206 *
207 * @param[in] path - the file path.
208 * @return pointer to the handler or nullptr if not found.
209 */
210 GenericBlobInterface* getHandler(const std::string& path);
211
212 /**
213 * Given a session id will return associated handler.
214 *
215 * @param[in] session - the session.
216 * @return pointer to the handler or nullptr if not found.
217 */
218 GenericBlobInterface* getHandler(uint16_t session);
219
220 /**
221 * Given a session id will return associated metadata, including
222 * the handler and the flags passed into open.
223 *
224 * @param[in] session - the session.
225 * @return pointer to the information or nullptr if not found.
226 */
227 SessionInfo* getSessionInfo(uint16_t session);
228
229 /**
230 * Given a session id will return associated path.
231 *
232 * @param[in] session - the session.
233 * @return the path or "" on failure.
234 */
235 std::string getPath(uint16_t session) const;
236
237 private:
238 void incrementOpen(const std::string& path);
239 void decrementOpen(const std::string& path);
240 int getOpen(const std::string& path) const;
241
242 /* The next session ID to use */
243 uint16_t next;
244 /* Temporary list of blobIds used for enumeration. */
245 std::vector<std::string> ids;
246 /* List of Blob handler. */
247 std::vector<std::unique_ptr<GenericBlobInterface>> handlers;
248 /* Mapping of session ids to blob handlers and the path used with open.
249 */
250 std::unordered_map<uint16_t, SessionInfo> sessions;
251 /* Mapping of open blobIds */
252 std::unordered_map<std::string, int> openFiles;
253};
254} // namespace blobs