c335fd3519e96f33631cf4ceda513e63424dc7c1
[asterisk/asterisk.git] / include / asterisk / bucket.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Bucket File API
21  * \author Joshua Colp <jcolp@digium.com>
22  * \ref AstBucket
23  */
24
25 /*!
26  * \page AstBucket Bucket File API
27  *
28  * Bucket is an API which provides directory and file access in a generic fashion. It is
29  * implemented as a thin wrapper over the sorcery data access layer API and is written in
30  * a pluggable fashion to allow different backend storage mechanisms.
31  *
32  */
33
34 #ifndef _ASTERISK_BUCKET_H
35 #define _ASTERISK_BUCKET_H
36
37 #if defined(__cplusplus) || defined(c_plusplus)
38 extern "C" {
39 #endif
40
41 #include "asterisk/sorcery.h"
42
43 /*! \brief Opaque structure for internal details about a scheme */
44 struct ast_bucket_scheme;
45
46 /*! \brief Bucket metadata structure, AO2 key value pair */
47 struct ast_bucket_metadata {
48         /*! \brief Name of the attribute */
49         const char *name;
50         /*! \brief Value of the attribute */
51         const char *value;
52         /*! \brief Storage for the above name and value */
53         char data[0];
54 };
55
56 /*! \brief Bucket structure, contains other buckets and files */
57 struct ast_bucket {
58         /*! \brief Sorcery object information */
59         SORCERY_OBJECT(details);
60         /*! \brief Scheme implementation in use */
61         struct ast_bucket_scheme *scheme_impl;
62         /*! \brief Stringfields */
63         AST_DECLARE_STRING_FIELDS(
64                 /*! \brief Name of scheme in use */
65                 AST_STRING_FIELD(scheme);
66         );
67         /*! \brief When this bucket was created */
68         struct timeval created;
69         /*! \brief When this bucket was last modified */
70         struct timeval modified;
71         /*! \brief Container of string URIs of buckets within this bucket */
72         struct ao2_container *buckets;
73         /*! \brief Container of string URIs of files within this bucket */
74         struct ao2_container *files;
75 };
76
77 /*! \brief Bucket file structure, contains reference to file and information about it */
78 struct ast_bucket_file {
79         /*! \brief Sorcery object information */
80         SORCERY_OBJECT(details);
81         /*! \brief Scheme implementation in use */
82         struct ast_bucket_scheme *scheme_impl;
83         /*! \brief Stringfields */
84         AST_DECLARE_STRING_FIELDS(
85                 /*! \brief Name of scheme in use */
86                 AST_STRING_FIELD(scheme);
87         );
88         /*! \brief When this file was created */
89         struct timeval created;
90         /*! \brief When this file was last modified */
91         struct timeval modified;
92         /*! \brief Container of metadata attributes about file */
93         struct ao2_container *metadata;
94         /*! \brief Local path to this file */
95         char path[PATH_MAX];
96 };
97
98 /*!
99  * \brief A callback function invoked when creating a file snapshot
100  *
101  * \param file Pointer to the file snapshot
102  *
103  * \retval 0 success
104  * \retval -1 failure
105  */
106 typedef int (*bucket_file_create_cb)(struct ast_bucket_file *file);
107
108 /*!
109  * \brief A callback function invoked when destroying a file snapshot
110  *
111  * \param file Pointer to the file snapshot
112  */
113 typedef void (*bucket_file_destroy_cb)(struct ast_bucket_file *file);
114
115 /*!
116  * \brief Initialize bucket support
117  *
118  * \retval 0 success
119  * \retval -1 failure
120  */
121 int ast_bucket_init(void);
122
123 /*!
124  * \brief Register support for a specific scheme
125  *
126  * \param name Name of the scheme, used to find based on scheme in URIs
127  * \param bucket Sorcery wizard used for buckets
128  * \param file Sorcery wizard used for files
129  * \param create_cb Required file snapshot creation callback
130  * \param destroy_cb Optional file snapshot destruction callback
131  *
132  * \retval 0 success
133  * \retval -1 failure
134  *
135  * \note Once a scheme has been registered it can not be unregistered
136  */
137 #define ast_bucket_scheme_register(name, bucket, file, create_cb, destroy_cb) __ast_bucket_scheme_register(name, bucket, file, create_cb, destroy_cb, AST_MODULE_SELF)
138
139 /*!
140  * \brief Register support for a specific scheme
141  *
142  * \param name Name of the scheme, used to find based on scheme in URIs
143  * \param bucket Sorcery wizard used for buckets
144  * \param file Sorcery wizard used for files
145  * \param create_cb Required file snapshot creation callback
146  * \param destroy_cb Optional file snapshot destruction callback
147  * \param module The module which implements this scheme
148  *
149  * \retval 0 success
150  * \retval -1 failure
151  *
152  * \note Once a scheme has been registered it can not be unregistered
153  */
154 int __ast_bucket_scheme_register(const char *name, struct ast_sorcery_wizard *bucket,
155         struct ast_sorcery_wizard *file, bucket_file_create_cb create_cb,
156         bucket_file_destroy_cb destroy_cb, struct ast_module *module);
157
158 /*!
159  * \brief Set a metadata attribute on a file to a specific value
160  *
161  * \param file The bucket file
162  * \param name Name of the attribute
163  * \param value Value of the attribute
164  *
165  * \retval 0 success
166  * \retval -1 failure
167  *
168  * \note This function will overwrite an existing attribute of the same name, unless an error
169  * occurs. If an error occurs the existing attribute is left alone.
170  */
171 int ast_bucket_file_metadata_set(struct ast_bucket_file *file, const char *name, const char *value);
172
173 /*!
174  * \brief Unset a specific metadata attribute on a file
175  *
176  * \param file The bucket file
177  * \param name Name of the attribute
178  *
179  * \retval 0 success
180  * \retval -1 failure
181  */
182 int ast_bucket_file_metadata_unset(struct ast_bucket_file *file, const char *name);
183
184 /*!
185  * \brief Retrieve a metadata attribute from a file
186  *
187  * \param file The bucket file
188  * \param name Name of the attribute
189  *
190  * \retval non-NULL if found
191  * \retval NULL if not found
192  *
193  * \note The object is returned with reference count increased
194  */
195 struct ast_bucket_metadata *ast_bucket_file_metadata_get(struct ast_bucket_file *file, const char *name);
196
197 /*!
198  * \brief Allocate a new bucket
199  *
200  * \param uri Complete URI for the bucket
201  *
202  * \param non-NULL success
203  * \param NULL failure
204  *
205  * \note This only creates a local bucket object, to persist in backend storage you must call
206  * ast_bucket_create
207  */
208 struct ast_bucket *ast_bucket_alloc(const char *uri);
209
210 /*!
211  * \brief Create a new bucket in backend storage
212  *
213  * \param bucket The bucket
214  *
215  * \retval 0 success
216  * \retval -1 failure
217  */
218 int ast_bucket_create(struct ast_bucket *bucket);
219
220 /*!
221  * \brief Clone a bucket
222  *
223  * This will create a copy of the passed in \c ast_bucket structure. While
224  * all properties of the \c ast_bucket structure are copied, any metadata
225  * in the original structure simply has its reference count increased.
226  *
227  * \param file The bucket to clone
228  *
229  * \retval non-NULL success
230  * \retval NULL failure
231  *
232  * \note This operation should be called prior to updating a bucket
233  * object, as \c ast_bucket instances are immutable
234  */
235 struct ast_bucket *ast_bucket_clone(struct ast_bucket *bucket);
236
237 /*!
238  * \brief Delete a bucket from backend storage
239  *
240  * \param bucket The bucket
241  *
242  * \retval 0 success
243  * \retval -1 failure
244  */
245 int ast_bucket_delete(struct ast_bucket *bucket);
246
247 /*!
248  * \brief Retrieve information about a bucket
249  *
250  * \param uri Complete URI of the bucket
251  *
252  * \retval non-NULL if found
253  * \retval NULL if not found
254  *
255  * \note The object is returned with reference count increased
256  */
257 struct ast_bucket *ast_bucket_retrieve(const char *uri);
258
259 /*!
260  * \brief Retrieve whether or not the backing datastore views the bucket as stale
261  * \since 14.0.0
262  *
263  * This function will ask whatever data storage backs the bucket's schema
264  * type if the current instance of the object is stale. It will not
265  * update the bucket object itself, as said objects are immutable. If the
266  * caller of this function would like to update the object, it should perform
267  * a retrieve operation.
268  *
269  * \param bucket The bucket object to check
270  *
271  * \retval 0 if \c bucket is not stale
272  * \retval 1 if \c bucket is stale
273  */
274 int ast_bucket_is_stale(struct ast_bucket *bucket);
275
276 /*!
277  * \brief Add an observer for bucket creation and deletion operations
278  *
279  * \param callbacks Implementation of the sorcery observer interface
280  *
281  * \retval 0 success
282  * \retval -1 failure
283  *
284  * \note You must be ready to accept observer invocations before this function is called
285  */
286 int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks);
287
288 /*!
289  * \brief Remove an observer from bucket creation and deletion
290  *
291  * \param callbacks Implementation of the sorcery observer interface
292  */
293 void ast_bucket_observer_remove(const struct ast_sorcery_observer *callbacks);
294
295 /*!
296  * \brief Get a JSON representation of a bucket
297  *
298  * \param bucket The specific bucket
299  *
300  * \retval non-NULL success
301  * \retval NULL failure
302  *
303  * \note The returned ast_json object must be unreferenced using ast_json_unref
304  */
305 struct ast_json *ast_bucket_json(const struct ast_bucket *bucket);
306
307 /*!
308  * \brief Allocate a new bucket file
309  *
310  * \param uri Complete URI for the bucket file
311  *
312  * \param non-NULL success
313  * \param NULL failure
314  *
315  * \note This only creates a local bucket file object, to persist in backend storage you must call
316  * ast_bucket_file_create
317  */
318 struct ast_bucket_file *ast_bucket_file_alloc(const char *uri);
319
320 /*!
321  * \brief Create a new bucket file in backend storage
322  *
323  * \param file The bucket file
324  *
325  * \retval 0 success
326  * \retval -1 failure
327  */
328 int ast_bucket_file_create(struct ast_bucket_file *file);
329
330 /*!
331  * \brief Copy a bucket file to a new URI
332  *
333  * \param file The source bucket file
334  * \param uri The new URI
335  *
336  * \retval non-NULL success
337  * \retval NULL failure
338  *
339  * \note This operation stages things locally, you must call ast_bucket_file_create on the file
340  * that is returned to commit the copy to backend storage
341  *
342  */
343 struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri);
344
345 /*!
346  * \brief Clone a bucket file
347  *
348  * This will create a copy of the passed in \c ast_bucket_file structure. While
349  * all properties of the \c ast_bucket_file structure are copied, any metadata
350  * in the original structure simply has its reference count increased. Note that
351  * this copies the structure, not the underlying file.
352  *
353  * \param file The bucket file to clone
354  *
355  * \retval non-NULL success
356  * \retval NULL failure
357  *
358  * \note This operation should be called prior to updating a bucket file
359  * object, as \c ast_bucket_file instances are immutable
360  */
361 struct ast_bucket_file *ast_bucket_file_clone(struct ast_bucket_file *file);
362
363 /*!
364  * \brief Update an existing bucket file in backend storage
365  *
366  * \param file The bucket file
367  *
368  * \retval 0 success
369  * \retval -1 failure
370  *
371  * \note This operation will update both the actual content of the file and the metadata associated with it
372  */
373 int ast_bucket_file_update(struct ast_bucket_file *file);
374
375 /*!
376  * \brief Delete a bucket file from backend storage
377  *
378  * \param file The bucket file
379  *
380  * \retval 0 success
381  * \retval -1 failure
382  */
383 int ast_bucket_file_delete(struct ast_bucket_file *file);
384
385 /*!
386  * \brief Retrieve a bucket file
387  *
388  * \param uri Complete URI of the bucket file
389  *
390  * \retval non-NULL if found
391  * \retval NULL if not found
392  *
393  * \note The object is returned with reference count increased
394  */
395 struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri);
396
397 /*!
398  * \brief Retrieve whether or not the backing datastore views the bucket file as stale
399  * \since 14.0.0
400  *
401  * This function will ask whatever data storage backs the bucket file's schema
402  * type if the current instance of the object is stale. It will not
403  * update the bucket file object itself, as said objects are immutable. If the
404  * caller of this function would like to update the object, it should perform
405  * a retrieve operation.
406  *
407  * \param bucket_file The bucket file object to check
408  *
409  * \retval 0 if \c bucket_file is not stale
410  * \retval 1 if \c bucket_file is stale
411  */
412 int ast_bucket_file_is_stale(struct ast_bucket_file *file);
413
414 /*!
415  * \brief Add an observer for bucket file creation and deletion operations
416  *
417  * \param callbacks Implementation of the sorcery observer interface
418  *
419  * \retval 0 success
420  * \retval -1 failure
421  *
422  * \note You must be ready to accept observer invocations before this function is called
423  */
424 int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks);
425
426 /*!
427  * \brief Remove an observer from bucket file creation and deletion
428  *
429  * \param callbacks Implementation of the sorcery observer interface
430  */
431 void ast_bucket_file_observer_remove(const struct ast_sorcery_observer *callbacks);
432
433 /*!
434  * \brief Get a JSON representation of a bucket file
435  *
436  * \param file The specific bucket file
437  *
438  * \retval non-NULL success
439  * \retval NULL failure
440  *
441  * \note The returned ast_json object must be unreferenced using ast_json_unref
442  */
443 struct ast_json *ast_bucket_file_json(const struct ast_bucket_file *file);
444
445 /*!
446  * \brief Common file snapshot creation callback for creating a temporary file
447  *
448  * \param file Pointer to the file snapshot
449  *
450  * \retval 0 success
451  * \retval -1 failure
452  */
453 int ast_bucket_file_temporary_create(struct ast_bucket_file *file);
454
455 /*!
456  * \brief Common file snapshot destruction callback for deleting a temporary file
457  *
458  * \param file Pointer to the file snapshot
459  */
460 void ast_bucket_file_temporary_destroy(struct ast_bucket_file *file);
461
462 #if defined(__cplusplus) || defined(c_plusplus)
463 }
464 #endif
465
466 #endif /* _ASTERISK_BUCKET_H */