2 # ============LICENSE_START===============================================
3 # Copyright (C) 2020 Nordix Foundation. All rights reserved.
4 # ========================================================================
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
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 implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 # ============LICENSE_END=================================================
19 from flask import Flask, request, Response
20 from time import sleep
22 from datetime import datetime
27 # Disable all logging of GET on reading counters and db
28 class AjaxFilter(logging.Filter):
29 def filter(self, record):
30 return ("/counter/" not in record.getMessage()) and ("/db" not in record.getMessage())
32 log = logging.getLogger('werkzeug')
33 log.addFilter(AjaxFilter())
37 # list of callback messages
49 # Request and response constants
50 CALLBACK_URL="/callbacks/<string:id>"
51 APP_READ_URL="/get-event/<string:id>"
52 APP_READ_ALL_URL="/get-all-events/<string:id>"
55 MIME_TEXT="text/plain"
56 MIME_JSON="application/json"
57 CAUGHT_EXCEPTION="Caught exception: "
58 SERVER_ERROR="Server error :"
59 TIME_STAMP="cr-timestamp"
67 ### Callback interface, for control
69 # Fetch the oldest callback message for an id
70 # URI and parameter, (GET): /get-event/<id>
71 # response: message + 200 or just 204 or just 500(error)
72 @app.route(APP_READ_URL,
74 def receiveresponse(id):
76 global cntr_msg_fetched
79 if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
81 cntr_callbacks[id][1]+=1
82 msg=msg_callbacks[id][0]
83 print("Fetching msg for id: "+id+", msg="+str(msg))
85 del msg_callbacks[id][0]
86 return json.dumps(msg),200
87 print("No messages for id: "+id)
88 except Exception as e:
89 print(CAUGHT_EXCEPTION+str(e))
95 # Fetch all callback message for an id in an array
96 # URI and parameter, (GET): /get-all-events/<id>
97 # response: message + 200 or just 500(error)
98 @app.route(APP_READ_ALL_URL,
100 def receiveresponse_all(id):
102 global cntr_msg_fetched
105 if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
106 cntr_msg_fetched+=len(msg_callbacks[id])
107 cntr_callbacks[id][1]+=len(msg_callbacks[id])
108 msg=msg_callbacks[id]
109 print("Fetching all msgs for id: "+id+", msg="+str(msg))
111 del sub_msg[TIME_STAMP]
112 del msg_callbacks[id]
113 return json.dumps(msg),200
114 print("No messages for id: "+id)
115 except Exception as e:
116 print(CAUGHT_EXCEPTION+str(e))
117 traceback.print_exc()
121 return json.dumps(msg),200
123 # Receive a callback message
124 # URI and payload, (PUT or POST): /callbacks/<id> <json messages>
125 # response: OK 200 or 500 for other errors
126 @app.route(CALLBACK_URL,
127 methods=['PUT','POST'])
128 def events_write(id):
130 global cntr_msg_callbacks
133 print("Received callback for id: "+id +", content-type="+request.content_type)
135 if (request.content_type == MIME_JSON):
137 msg = json.loads(data)
138 print("Payload(json): "+str(msg))
141 print("Payload(content-type="+request.content_type+"). Setting empty json as payload")
142 except Exception as e:
144 print("(Exception) Payload does not contain any json, setting empty json as payload")
145 traceback.print_exc()
147 cntr_msg_callbacks += 1
148 msg[TIME_STAMP]=str(datetime.now())
149 if (id in msg_callbacks.keys()):
150 msg_callbacks[id].append(msg)
153 msg_callbacks[id].append(msg)
155 if (id in cntr_callbacks.keys()):
156 cntr_callbacks[id][0] += 1
158 cntr_callbacks[id]=[]
159 cntr_callbacks[id].append(1)
160 cntr_callbacks[id].append(0)
162 except Exception as e:
163 print(CAUGHT_EXCEPTION+str(e))
164 traceback.print_exc()
169 ### Functions for test ###
171 # Dump the whole db of current callbacks
172 # URI and parameter, (GET): /db
173 # response: message + 200
174 @app.route(DUMP_ALL_URL,
177 return json.dumps(msg_callbacks),200
179 ### Functions for metrics read out ###
181 @app.route('/counter/received_callbacks',
183 def requests_submitted():
184 req_id = request.args.get('id')
186 return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
188 if (req_id in cntr_callbacks.keys()):
189 return Response(str(cntr_callbacks[req_id][0]), status=200, mimetype=MIME_TEXT)
191 return Response(str("0"), status=200, mimetype=MIME_TEXT)
193 @app.route('/counter/fetched_callbacks',
195 def requests_fetched():
196 req_id = request.args.get('id')
198 return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
200 if (req_id in cntr_callbacks.keys()):
201 return Response(str(cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
203 return Response(str("0"), status=200, mimetype=MIME_TEXT)
205 @app.route('/counter/current_messages',
207 def current_messages():
208 req_id = request.args.get('id')
210 return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
212 if (req_id in cntr_callbacks.keys()):
213 return Response(str(cntr_callbacks[req_id][0]-cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
215 return Response(str("0"), status=200, mimetype=MIME_TEXT)
220 # Reset all messsages and counters
222 methods=['GET', 'POST', 'PUT'])
225 global cntr_msg_fetched
226 global cntr_msg_callbacks
227 global cntr_callbacks
234 return Response('OK', status=200, mimetype=MIME_TEXT)
236 ### Main function ###
238 if __name__ == "__main__":
239 app.run(port=HOST_PORT, host=HOST_IP)