2 # Thierry Parmentelat - INRIA
6 from types import StringTypes
8 from PLC.Table import Row, Table
9 from PLC.Parameter import Parameter
10 from PLC.Filter import Filter
12 class ForeignSlice (Row) :
14 This object stores information about slices hosted on
15 other peering instances of myplc
19 primary_key = 'slice_id'
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"),
34 def __init__(self,api,fields={},uptodate=True):
35 Row.__init__(self,api,fields)
36 self.uptodate=uptodate
38 def validate_created(self,timestamp):
39 return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(timestamp))
41 def validate_expires(self,timestamp):
42 return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(timestamp))
44 def purge_peer_slice (self,commit=True):
45 sql = "DELETE FROM peer_slice WHERE slice_id=%d"%self['slice_id']
50 def purge_slice_node (self,commit=True):
51 sql = "DELETE FROM slice_node WHERE slice_id=%d"%self['slice_id']
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)
68 def update_slice_nodes (self, node_ids):
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
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)
79 def delete (self, commit=True):
81 Delete existing foreign slice.
83 self.purge_peer_slice()
84 self['is_deleted']=True
88 class ForeignSlices (Table):
89 def __init__ (self, api, foreign_slice_filter = None, columns = None):
90 Table.__init__(self, api, ForeignSlice, columns)
93 sql += "SELECT %s FROM view_foreign_slices " % ", ".join(self.columns)
94 sql += "WHERE is_deleted IS False "
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")