4f75b6fe095406efda35265db15d793ae48b6179
[pithos] / pithos / backends / base.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 class NotAllowedError(Exception):
35     pass
36
37 class BaseBackend(object):
38     """Abstract backend class that serves as a reference for actual implementations.
39     
40     The purpose of the backend is to provide the necessary functions for handling data
41     and metadata. It is responsible for the actual storage and retrieval of information.
42     
43     Note that the account level is always valid as it is checked from another subsystem.
44     
45     When not replacing metadata, keys with empty values should be deleted.
46     
47     The following variables should be available:
48         'hash_algorithm': Suggested is 'sha256'
49         'block_size': Suggested is 4MB
50     """
51     
52     def delete_account(self, user, account):
53         """Delete the account with the given name.
54         
55         Raises:
56             NotAllowedError: Operation not permitted
57             IndexError: Account is not empty
58         """
59         return
60     
61     def get_account_meta(self, user, account, until=None):
62         """Return a dictionary with the account metadata.
63         
64         The keys returned are all user-defined, except:
65             'name': The account name
66             'count': The number of containers (or 0)
67             'bytes': The total data size (or 0)
68             'modified': Last modification timestamp (overall)
69             'until_timestamp': Last modification until the timestamp provided
70         
71         Raises:
72             NotAllowedError: Operation not permitted
73         """
74         return {}
75     
76     def update_account_meta(self, user, account, meta, replace=False):
77         """Update the metadata associated with the account.
78         
79         Parameters:
80             'meta': Dictionary with metadata to update
81             'replace': Replace instead of update
82         
83         Raises:
84             NotAllowedError: Operation not permitted
85         """
86         return
87     
88     def list_containers(self, user, account, marker=None, limit=10000, until=None):
89         """Return a list of container (name, version_id) tuples existing under an account.
90         
91         Parameters:
92             'marker': Start list from the next item after 'marker'
93             'limit': Number of containers to return
94         
95         Raises:
96             NotAllowedError: Operation not permitted
97         """
98         return []
99     
100     def put_container(self, user, account, container):
101         """Create a new container with the given name.
102         
103         Raises:
104             NotAllowedError: Operation not permitted
105             NameError: Container already exists
106         """
107         return
108     
109     def delete_container(self, user, account, container):
110         """Delete the container with the given name.
111         
112         Raises:
113             NotAllowedError: Operation not permitted
114             NameError: Container does not exist
115             IndexError: Container is not empty
116         """
117         return
118     
119     def get_container_meta(self, user, account, container, until=None):
120         """Return a dictionary with the container metadata.
121         
122         The keys returned are all user-defined, except:
123             'name': The container name
124             'count': The number of objects
125             'bytes': The total data size
126             'modified': Last modification timestamp (overall)
127             'until_timestamp': Last modification until the timestamp provided
128         
129         Raises:
130             NotAllowedError: Operation not permitted
131             NameError: Container does not exist
132         """
133         return {}
134     
135     def update_container_meta(self, user, account, container, meta, replace=False):
136         """Update the metadata associated with the container.
137         
138         Parameters:
139             'meta': Dictionary with metadata to update
140             'replace': Replace instead of update
141         
142         Raises:
143             NotAllowedError: Operation not permitted
144             NameError: Container does not exist
145         """
146         return
147     
148     def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
149         """Return a list of object (name, version_id) tuples existing under a container.
150         
151         Parameters:
152             'prefix': List objects starting with 'prefix'
153             'delimiter': Return unique names before 'delimiter' and after 'prefix'
154             'marker': Start list from the next item after 'marker'
155             'limit': Number of objects to return
156             'virtual': If not set, the result will only include names starting\
157                        with 'prefix' and ending without a 'delimiter' or with\
158                        the first occurance of the 'delimiter' after 'prefix'.\
159                        If set, the result will include all names after 'prefix',\
160                        up to and including the 'delimiter' if it is found
161             'keys': Include objects that have meta with the keys in the list
162         
163         Raises:
164             NotAllowedError: Operation not permitted
165             NameError: Container does not exist
166         """
167         return []
168     
169     def list_object_meta(self, user, account, container, until=None):
170         """Return a list with all the container's object meta keys.
171         
172         Raises:
173             NotAllowedError: Operation not permitted
174             NameError: Container does not exist
175         """
176         return []
177     
178     def get_object_meta(self, user, account, container, name, version=None):
179         """Return a dictionary with the object metadata.
180         
181         The keys returned are all user-defined, except:
182             'name': The object name
183             'bytes': The total data size
184             'modified': Last modification timestamp (overall)
185             'version': The version identifier
186             'version_timestamp': The version's modification timestamp
187         
188         Raises:
189             NotAllowedError: Operation not permitted
190             NameError: Container/object does not exist
191             IndexError: Version does not exist
192         """
193         return {}
194     
195     def update_object_meta(self, user, account, container, name, meta, replace=False):
196         """Update the metadata associated with the object.
197         
198         Parameters:
199             'meta': Dictionary with metadata to update
200             'replace': Replace instead of update
201         
202         Raises:
203             NotAllowedError: Operation not permitted
204             NameError: Container/object does not exist
205         """
206         return
207     
208     def get_object_permissions(self, user, account, container, name):
209         """Return the path from which this object gets its permissions from,\
210         along with a dictionary containing the permissions.
211         
212         The keys are:
213             'read': The object is readable by the users/groups in the list
214             'write': The object is writable by the users/groups in the list
215         
216         Raises:
217             NotAllowedError: Operation not permitted
218             NameError: Container/object does not exist
219         """
220         return {}
221     
222     def update_object_permissions(self, user, account, container, name, permissions):
223         """Update the permissions associated with the object.
224         
225         Parameters:
226             'permissions': Dictionary with permissions to update
227         
228         Raises:
229             NotAllowedError: Operation not permitted
230             NameError: Container/object does not exist
231             ValueError: Invalid users/groups in permissions
232             AttributeError: Can not set permissions, as this object\
233                 is already shared/private by another object higher\
234                 in the hierarchy, or setting permissions here will\
235                 invalidate other permissions deeper in the hierarchy
236         """
237         return
238     
239     def get_object_hashmap(self, user, account, container, name, version=None):
240         """Return the object's size and a list with partial hashes.
241         
242         Raises:
243             NotAllowedError: Operation not permitted
244             NameError: Container/object does not exist
245             IndexError: Version does not exist
246         """
247         return 0, []
248     
249     def update_object_hashmap(self, user, account, container, name, size, hashmap, meta={}, replace_meta=False, permissions=None):
250         """Create/update an object with the specified size and partial hashes.
251         
252         Parameters:
253             'dest_meta': Dictionary with metadata to change
254             'replace_meta': Replace metadata instead of update
255             'permissions': Updated object permissions
256         
257         Raises:
258             NotAllowedError: Operation not permitted
259             NameError: Container does not exist
260             ValueError: Invalid users/groups in permissions
261             AttributeError: Can not set permissions
262         """
263         return
264     
265     def copy_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None, src_version=None):
266         """Copy an object's data and metadata.
267         
268         Parameters:
269             'dest_meta': Dictionary with metadata to change from source to destination
270             'replace_meta': Replace metadata instead of update
271             'permissions': New object permissions
272             'src_version': Copy from the version provided
273         
274         Raises:
275             NotAllowedError: Operation not permitted
276             NameError: Container/object does not exist
277             IndexError: Version does not exist
278             ValueError: Invalid users/groups in permissions
279             AttributeError: Can not set permissions
280         """
281         return
282     
283     def move_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None):
284         """Move an object's data and metadata.
285         
286         Parameters:
287             'dest_meta': Dictionary with metadata to change from source to destination
288             'replace_meta': Replace metadata instead of update
289             'permissions': New object permissions
290         
291         Raises:
292             NotAllowedError: Operation not permitted
293             NameError: Container/object does not exist
294             ValueError: Invalid users/groups in permissions
295             AttributeError: Can not set permissions
296         """
297         return
298     
299     def delete_object(self, user, account, container, name):
300         """Delete an object.
301         
302         Raises:
303             NotAllowedError: Operation not permitted
304             NameError: Container/object does not exist
305         """
306         return
307     
308     def list_versions(self, user, account, container, name):
309         """Return a list of all (version, version_timestamp) tuples for an object.
310         
311         Raises:
312             NotAllowedError: Operation not permitted
313         """
314         return []
315     
316     def get_block(self, hash):
317         """Return a block's data.
318         
319         Raises:
320             NameError: Block does not exist
321         """
322         return ''
323     
324     def put_block(self, data):
325         """Store a block and return the hash."""
326         return 0
327     
328     def update_block(self, hash, data, offset=0):
329         """Update a known block and return the hash.
330         
331         Raises:
332             IndexError: Offset or data outside block limits
333         """
334         return 0