317b03668d875afa072e390b170ac6c6d9863ada
[plcapi.git] / PLC / ForeignSlices.py
1 #
2 # Thierry Parmentelat - INRIA
3
4 import time
5
6 from types import StringTypes
7
8 from PLC.Table import Row, Table
9 from PLC.Parameter import Parameter
10 from PLC.Filter import Filter
11
12 class ForeignSlice (Row) :
13     """
14     This object stores information about slices hosted on 
15     other peering instances of myplc
16     """
17
18     table_name = 'slices'
19     primary_key = 'slice_id'
20
21     fields = {
22         'slice_id': Parameter (int, "Slice Id"),
23         'name' :    Parameter (str, "Slice name"),
24         'peer_id': Parameter (str, "Peer id"),
25         'instantiation': Parameter(str, "Slice instantiation state"),
26         'url': Parameter(str, "URL further describing this slice", max = 254, nullok = True),
27         'description': Parameter(str, "Slice description", max = 2048, nullok = True),
28         'max_nodes': Parameter(int, "Maximum number of nodes that can be assigned to this slice"),
29         'created': Parameter(int, "Date and time when slice was created, in seconds since UNIX epoch", ro = True),
30         'expires': Parameter(int, "Date and time when slice expires, in seconds since UNIX epoch"),
31         'node_ids' : Parameter([int], "List of nodes in this slice"),
32         }
33
34     def __init__(self,api,fields={},uptodate=True):
35         Row.__init__(self,api,fields)
36         self.uptodate=uptodate
37
38     def validate_created(self,timestamp):
39         return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(timestamp))
40
41     def validate_expires(self,timestamp):
42         return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(timestamp))
43
44     def purge_peer_slice (self,commit=True):
45         sql = "DELETE FROM peer_slice WHERE slice_id=%d"%self['slice_id']
46         self.api.db.do(sql)
47         if commit:
48             self.api.db.commit()
49
50     def purge_slice_node (self,commit=True):
51         sql = "DELETE FROM slice_node WHERE slice_id=%d"%self['slice_id']
52         self.api.db.do(sql)
53         if commit:
54             self.api.db.commit()
55
56     def add_slice_nodes (self, node_ids, commit=True):
57         slice_id = self['slice_id']
58         ### xxx needs to be optimized
59         ### tried to figure a way to use a single sql statement
60         ### like: insert into table (x,y) values (1,2),(3,4);
61         ### but apparently this is not supported under postgresql
62         for node_id in node_ids:
63             sql="INSERT INTO slice_node VALUES (%d,%d)"%(slice_id,node_id)
64             self.api.db.do(sql)
65         if commit:
66             self.api.db.commit()
67
68     def update_slice_nodes (self, node_ids):
69         # xxx to be optimized
70         # we could compute the (set) difference between
71         # current and updated set of node_ids
72         # and invoke the DB only based on that
73         #
74         # for now : clean all entries for this slice
75         self.purge_slice_node()
76         # and re-install new list
77         self.add_slice_nodes (node_ids)
78
79     def delete (self, commit=True):
80         """
81         Delete existing foreign slice.
82         """
83         self.purge_peer_slice()
84         self['is_deleted']=True
85         self.sync(commit)
86         
87
88 class ForeignSlices (Table):
89     def __init__ (self, api, foreign_slice_filter = None, columns = None):
90         Table.__init__(self, api, ForeignSlice, columns)
91
92         sql = ""
93         sql += "SELECT %s FROM view_foreign_slices " % ", ".join(self.columns)
94         sql += "WHERE is_deleted IS False "
95
96         if foreign_slice_filter is not None:
97             if isinstance(foreign_slice_filter, (list, tuple, set)):
98                 # Separate the list into integers and strings
99                 ints = filter(lambda x: isinstance(x, (int, long)), foreign_slice_filter)
100                 strs = filter(lambda x: isinstance(x, StringTypes), foreign_slice_filter)
101                 foreign_slice_filter = Filter(ForeignSlice.fields, {'slice_id': ints, 'name': strs})
102                 sql += " AND (%s)" % foreign_slice_filter.sql(api, "OR")
103             elif isinstance(foreign_slice_filter, dict):
104                 foreign_slice_filter = Filter(ForeignSlice.fields, foreign_slice_filter)
105                 sql += " AND (%s)" % foreign_slice_filter.sql(api, "AND")
106
107         self.selectall(sql)
108