DeleteSliver supports call_id
[sfa.git] / sfa / managers / aggregate_manager_openflow.py
1 import sys
2
3 import socket
4 import struct
5
6 #The following is not essential
7 #from soaplib.wsgi_soap import SimpleWSGISoapApp
8 #from soaplib.serializers.primitive import *
9 #from soaplib.serializers.clazz import *
10
11 from sfa.util.faults import *
12 from sfa.util.xrn import urn_to_hrn
13 from sfa.util.rspec import RSpec
14 from sfa.server.registry import Registries
15 from sfa.util.config import Config
16 from sfa.plc.nodes import *
17 from sfa.util.callids import Callids
18
19 # Message IDs for all the SFA light calls
20 # This will be used by the aggrMgr controller
21 SFA_GET_RESOURCES = 101
22 SFA_CREATE_SLICE = 102
23 SFA_START_SLICE = 103
24 SFA_STOP_SLICE = 104
25 SFA_DELETE_SLICE = 105
26 SFA_GET_SLICES = 106
27 SFA_RESET_SLICES = 107
28
29 DEBUG = 1
30
31 def print_buffer(buf):
32     for i in range(0,len(buf)):
33         print('%x' % buf[i])
34
35 def extract(sock):
36     # Shud we first obtain the message length?
37     # msg_len = socket.ntohs(sock.recv(2))
38     msg = ""
39
40     while (1):
41         try:
42             chunk = sock.recv(1)
43         except socket.error, message:
44             if 'timed out' in message:
45                 break
46             else:
47                 sys.exit("Socket error: " + message)
48
49         if len(chunk) == 0:
50             break
51         msg += chunk
52
53     print 'Done extracting %d bytes of response from aggrMgr' % len(msg)
54     return msg
55    
56 def connect(server, port):
57     '''Connect to the Aggregate Manager module'''
58     sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
59     sock.connect ( ( server, port) )
60     sock.settimeout(1)
61     if DEBUG: print 'Connected!'
62     return sock
63     
64 def connect_aggrMgr():
65     (aggr_mgr_ip, aggr_mgr_port) = Config().get_openflow_aggrMgr_info()
66     if DEBUG: print """Connecting to port %d of %s""" % (aggr_mgr_port, aggr_mgr_ip)
67     return connect(aggr_mgr_ip, aggr_mgr_port)
68
69 def generate_slide_id(cred, hrn):
70     if cred == None:
71         cred = ""
72     if hrn == None:
73         hrn = ""
74     #return cred + '_' + hrn
75     return str(hrn)
76
77 def msg_aggrMgr(cred, hrn, msg_id):
78     slice_id = generate_slide_id(cred, hrn)
79
80     msg = struct.pack('> B%ds' % len(slice_id), msg_id, slice_id)
81     buf = struct.pack('> H', len(msg)+2) + msg
82
83     try:
84         aggrMgr_sock = connect_aggrMgr()
85         aggrMgr_sock.send(buf)
86         aggrMgr_sock.close()
87         return 1
88     except socket.error, message:
89         print "Socket error"
90     except IOerror, message:
91         print "IO error"
92     return 0
93
94 def start_slice(cred, xrn):
95     hrn = urn_to_hrn(xrn)[0]
96     if DEBUG: print "Received start_slice call"
97     return msg_aggrMgr(SFA_START_SLICE)
98
99 def stop_slice(cred, xrn):
100     hrn = urn_to_hrn(xrn)[0]
101     if DEBUG: print "Received stop_slice call"
102     return msg_aggrMgr(SFA_STOP_SLICE)
103
104 def DeleteSliver(cred, xrn, call_id):
105     if Callids().already_handled(call_id): return ""
106     hrn = urn_to_hrn(xrn)[0]
107     if DEBUG: print "Received DeleteSliver call"
108     return msg_aggrMgr(SFA_DELETE_SLICE)
109
110 def reset_slices(cred, xrn):
111     hrn = urn_to_hrn(xrn)[0]
112     if DEBUG: print "Received reset_slices call"
113     return msg_aggrMgr(SFA_RESET_SLICES)
114
115 ### Thierry: xxx this should ahve api as a first arg - probably outdated 
116 def CreateSliver(cred, xrn, rspec, call_id):
117     if Callids().already_handled(call_id): return ""
118
119     hrn = urn_to_hrn(xrn)[0]
120     if DEBUG: print "Received CreateSliver call"
121     slice_id = generate_slide_id(cred, hrn)
122
123     msg = struct.pack('> B%ds%ds' % (len(slice_id)+1, len(rspec)), SFA_CREATE_SLICE, slice_id, rspec)
124     buf = struct.pack('> H', len(msg)+2) + msg
125
126     try:
127         aggrMgr_sock = connect_aggrMgr()
128         aggrMgr_sock.send(buf)
129         if DEBUG: print "Sent %d bytes and closing connection" % len(buf)
130         aggrMgr_sock.close()
131
132         if DEBUG: print "----------------"
133         return rspec
134     except socket.error, message:
135         print "Socket error"
136     except IOerror, message:
137         print "IO error"
138     return ""
139
140 # Thierry : xxx this would need to handle call_id like the other AMs but is outdated...
141 def ListResources(cred, xrn=None):
142     hrn = urn_to_hrn(xrn)[0]
143     if DEBUG: print "Received ListResources call"
144     slice_id = generate_slide_id(cred, hrn)
145
146     msg = struct.pack('> B%ds' % len(slice_id), SFA_GET_RESOURCES, slice_id)
147     buf = struct.pack('> H', len(msg)+2) + msg
148
149     try:
150         aggrMgr_sock = connect_aggrMgr()
151         aggrMgr_sock.send(buf)
152         resource_list = extract(aggrMgr_sock);
153         aggrMgr_sock.close()
154
155         if DEBUG: print "----------------"
156         return resource_list 
157     except socket.error, message:
158         print "Socket error"
159     except IOerror, message:
160         print "IO error"
161     return None
162
163 """
164 Returns the request context required by sfatables. At some point, this mechanism should be changed
165 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
166 return the basic information needed in a dict.
167 """
168 def fetch_context(slice_hrn, user_hrn, contexts):
169     base_context = {'sfa':{'user':{'hrn':user_hrn}}}
170     return base_context
171
172 def main():
173     r = RSpec()
174     r.parseFile(sys.argv[1])
175     rspec = r.toDict()
176     CreateSliver(None,'plc',rspec,'call-id-plc')
177     
178 if __name__ == "__main__":
179     main()