blob: fa42c20478863ec4bbc3c99349096f1b9376928f [file] [log] [blame]
BjornMagnussonXA80a92002020-03-19 14:31:06 +01001
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
8#
9# http://www.apache.org/licenses/LICENSE-2.0
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 implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# ============LICENSE_END=================================================
17#
18
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010019from flask import Flask, request, Response
BjornMagnussonXA80a92002020-03-19 14:31:06 +010020from time import sleep
21import time
BjornMagnussonXA7b36db62020-11-23 10:57:57 +010022from datetime import datetime
BjornMagnussonXA80a92002020-03-19 14:31:06 +010023import json
BjornMagnussonXA80a92002020-03-19 14:31:06 +010024import traceback
BjornMagnussonXA7b36db62020-11-23 10:57:57 +010025import logging
26
27# Disable all logging of GET on reading counters and db
28class AjaxFilter(logging.Filter):
29 def filter(self, record):
30 return ("/counter/" not in record.getMessage()) and ("/db" not in record.getMessage())
31
32log = logging.getLogger('werkzeug')
33log.addFilter(AjaxFilter())
BjornMagnussonXA80a92002020-03-19 14:31:06 +010034
35app = Flask(__name__)
36
37# list of callback messages
38msg_callbacks={}
39
40# Server info
BjornMagnussonXA72667f12020-04-24 09:20:18 +020041HOST_IP = "::"
ecaiyanlinux113bf092020-08-01 14:05:17 +000042HOST_PORT = 2222
BjornMagnussonXA80a92002020-03-19 14:31:06 +010043
44# Metrics vars
45cntr_msg_callbacks=0
46cntr_msg_fetched=0
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010047cntr_callbacks={}
BjornMagnussonXA80a92002020-03-19 14:31:06 +010048
49# Request and response constants
50CALLBACK_URL="/callbacks/<string:id>"
51APP_READ_URL="/get-event/<string:id>"
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010052APP_READ_ALL_URL="/get-all-events/<string:id>"
53DUMP_ALL_URL="/db"
BjornMagnussonXA80a92002020-03-19 14:31:06 +010054
55MIME_TEXT="text/plain"
56MIME_JSON="application/json"
57CAUGHT_EXCEPTION="Caught exception: "
58SERVER_ERROR="Server error :"
BjornMagnussonXA7b36db62020-11-23 10:57:57 +010059TIME_STAMP="cr-timestamp"
BjornMagnussonXA80a92002020-03-19 14:31:06 +010060
61#I'm alive function
62@app.route('/',
63 methods=['GET'])
64def index():
65 return 'OK', 200
66
67### Callback interface, for control
68
69# Fetch the oldest callback message for an id
70# URI and parameter, (GET): /get-event/<id>
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010071# response: message + 200 or just 204 or just 500(error)
BjornMagnussonXA80a92002020-03-19 14:31:06 +010072@app.route(APP_READ_URL,
73 methods=['GET'])
74def receiveresponse(id):
75 global msg_callbacks
76 global cntr_msg_fetched
77
78 try:
79 if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
80 cntr_msg_fetched+=1
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010081 cntr_callbacks[id][1]+=1
82 msg=msg_callbacks[id][0]
83 print("Fetching msg for id: "+id+", msg="+str(msg))
BjornMagnussonXA7b36db62020-11-23 10:57:57 +010084 del msg[TIME_STAMP]
BjornMagnussonXA80a92002020-03-19 14:31:06 +010085 del msg_callbacks[id][0]
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010086 return json.dumps(msg),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +010087 print("No messages for id: "+id)
88 except Exception as e:
89 print(CAUGHT_EXCEPTION+str(e))
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010090 traceback.print_exc()
91 return "",500
BjornMagnussonXA80a92002020-03-19 14:31:06 +010092
93 return "",204
94
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010095# 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,
99 methods=['GET'])
100def receiveresponse_all(id):
101 global msg_callbacks
102 global cntr_msg_fetched
103
104 try:
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))
BjornMagnussonXA7b36db62020-11-23 10:57:57 +0100110 for sub_msg in msg:
111 del sub_msg[TIME_STAMP]
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100112 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()
118 return "",500
119
120 msg=[]
121 return json.dumps(msg),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100122
123# Receive a callback message
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100124# URI and payload, (PUT or POST): /callbacks/<id> <json messages>
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100125# response: OK 200 or 500 for other errors
126@app.route(CALLBACK_URL,
127 methods=['PUT','POST'])
128def events_write(id):
129 global msg_callbacks
130 global cntr_msg_callbacks
131
132 try:
133 print("Received callback for id: "+id +", content-type="+request.content_type)
134 try:
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100135 if (request.content_type == MIME_JSON):
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100136 data = request.data
137 msg = json.loads(data)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100138 print("Payload(json): "+str(msg))
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100139 else:
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100140 msg={}
141 print("Payload(content-type="+request.content_type+"). Setting empty json as payload")
142 except Exception as e:
143 msg={}
144 print("(Exception) Payload does not contain any json, setting empty json as payload")
145 traceback.print_exc()
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100146
147 cntr_msg_callbacks += 1
BjornMagnussonXA7b36db62020-11-23 10:57:57 +0100148 msg[TIME_STAMP]=str(datetime.now())
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100149 if (id in msg_callbacks.keys()):
150 msg_callbacks[id].append(msg)
151 else:
152 msg_callbacks[id]=[]
153 msg_callbacks[id].append(msg)
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100154
155 if (id in cntr_callbacks.keys()):
156 cntr_callbacks[id][0] += 1
157 else:
158 cntr_callbacks[id]=[]
159 cntr_callbacks[id].append(1)
160 cntr_callbacks[id].append(0)
161
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100162 except Exception as e:
163 print(CAUGHT_EXCEPTION+str(e))
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100164 traceback.print_exc()
165 return 'NOTOK',500
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100166
167 return 'OK',200
168
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100169### Functions for test ###
170
171# Dump the whole db of current callbacks
172# URI and parameter, (GET): /db
173# response: message + 200
174@app.route(DUMP_ALL_URL,
175 methods=['GET'])
176def dump_db():
177 return json.dumps(msg_callbacks),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100178
179### Functions for metrics read out ###
180
181@app.route('/counter/received_callbacks',
182 methods=['GET'])
183def requests_submitted():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100184 req_id = request.args.get('id')
185 if (req_id is None):
186 return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
187
188 if (req_id in cntr_callbacks.keys()):
189 return Response(str(cntr_callbacks[req_id][0]), status=200, mimetype=MIME_TEXT)
190 else:
191 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100192
193@app.route('/counter/fetched_callbacks',
194 methods=['GET'])
195def requests_fetched():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100196 req_id = request.args.get('id')
197 if (req_id is None):
198 return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
199
200 if (req_id in cntr_callbacks.keys()):
201 return Response(str(cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
202 else:
203 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100204
205@app.route('/counter/current_messages',
206 methods=['GET'])
207def current_messages():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100208 req_id = request.args.get('id')
209 if (req_id is None):
210 return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100211
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100212 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)
214 else:
215 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100216
217
218### Admin ###
219
220# Reset all messsages and counters
221@app.route('/reset',
222 methods=['GET', 'POST', 'PUT'])
223def reset():
224 global msg_callbacks
225 global cntr_msg_fetched
226 global cntr_msg_callbacks
BjornMagnussonXA7b36db62020-11-23 10:57:57 +0100227 global cntr_callbacks
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100228
229 msg_callbacks={}
230 cntr_msg_fetched=0
231 cntr_msg_callbacks=0
BjornMagnussonXA7b36db62020-11-23 10:57:57 +0100232 cntr_callbacks={}
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100233
234 return Response('OK', status=200, mimetype=MIME_TEXT)
235
236### Main function ###
237
238if __name__ == "__main__":
239 app.run(port=HOST_PORT, host=HOST_IP)