blob: bfd05731ccb7b38c6f7eade4e6ca685071837433 [file] [log] [blame]
srikanth116e6e82014-08-19 07:22:37 -07001#!/usr/bin/env python
2#
3# Copyright (c) 2013 Big Switch Networks, Inc.
4#
5# Licensed under the Eclipse Public License, Version 1.0 (the
6# "License"); you may not use this file except in compliance with the
7# License. You may obtain a copy of the License at
8#
9# http://www.eclipse.org/legal/epl-v10.html
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14# implied. See the License for the specific language governing
15# permissions and limitations under the License.
16#
17
18"""Polling interface for the polling services setup by the rest API"""
19
20import sys, os, time, random, json
21
22from packetstreamer import PacketStreamer
23from packetstreamer.ttypes import *
24
25from thrift import Thrift
26from thrift.transport import TSocket
27from thrift.transport import TTransport
28from thrift.protocol import TBinaryProtocol
29
30def sample_func(request, environ):
31 data = {
32 'pid': os.getpid(),
33 'random': int(random.random()*100),
34 }
35
36 return {
37 'status': '200 OK',
38 'body': json.dumps(data),
39 'headers': [('Content-type', 'application/json')], # list of tuples
40 }
41
42def getPackets_func(request, environ, sessionid):
43 retData = {}
44
45 try:
46 # Make socket
47 transport = TSocket.TSocket('localhost', 9090)
48 # Buffering is critical. Raw sockets are very slow
49 transport = TTransport.TFramedTransport(transport)
50 # Wrap in a protocol
51 protocol = TBinaryProtocol.TBinaryProtocol(transport)
52 # Create a client to use the protocol encoder
53 client = PacketStreamer.Client(protocol)
54 # Connect!
55 transport.open()
56
57 packets = client.getPackets(sessionid)
58
59 # Close!
60 transport.close()
61
62 retData = {
63 'status': '200 OK',
64 'body': json.dumps(packets),
65 'headers': [('Content-type', 'application/json')], # list of tuples
66 }
67
68 except Thrift.TException, tx:
69 retData = {
70 'status': '500 Internal Server Error',
71 'body': 'error: %s'%tx.message,
72 'headers': [('Content-type', 'application/json')], # list of tuples
73 }
74
75 return retData
76
77# The polling service
78# The service is driven by the urlpatterns tuples that list the specific function
79# to use for a matching pattern in URL. The pattern should not include initial '^/poll'.
80# For Example:
81# (r'^/sample', sample_func)
82#from sdncon.rest.poll import sample_func
83urlpatterns = [
84 (r'^/packets/(?P<sessionid>[A-Za-z0-9_.\-]+)/?$', getPackets_func),
85 (r'^/sample', sample_func)
86]
87
88import re, wsgiref.util
89
90def compile_patterns(urlpatterns):
91 return map(lambda pat: (re.compile(pat[0]), pat[1]), urlpatterns)
92
93def main(environ, start_response):
94 patterns = compile_patterns(urlpatterns)
95 request = environ['PATH_INFO']
96 response = None
97 status, body = '404 Not Found', 'Sorry, the requested resource "%s" was not found."' % request
98 headers = []
99 for (pat, func) in patterns:
100 m = pat.match(request)
101 if m:
102 args = m.groups()
103 if args:
104 response = func(request, environ, *args)
105 else:
106 response = func(request, environ)
107
108 status, body = response['status'], response['body']
109 if 'headers' in response:
110 headers.extend(response['headers'])
111 break
112 if 'Cache-Control' not in headers:
113 headers.append(('Cache-Control', 'no-cache'))
114 if 'Content-type' not in headers:
115 headers.append(('Content-type', 'text/plain'))
116 if 'Content-Length' not in headers:
117 headers.append(('Content-Length', str(len(body))))
118 start_response(status, headers)
119 return [body]
120
121if __name__ == "__main__":
122 def start_response(x, y):
123 print 'Status:', x
124 print 'Headers:', y
125
126 print 'Sample', sample_func(None, None)
127 print 'Response:', main({'PATH_INFO':'/sample/100'}, start_response)
128 print 'Response:', main({'PATH_INFO':'/xsample/100'}, start_response)