blob: fe0fbe4effdf334e9839cdf47d4be2d00d68c93b [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
22import datetime
23import json
BjornMagnussonXA80a92002020-03-19 14:31:06 +010024import traceback
25
26app = Flask(__name__)
27
28# list of callback messages
29msg_callbacks={}
30
31# Server info
BjornMagnussonXA72667f12020-04-24 09:20:18 +020032HOST_IP = "::"
ecaiyanlinux113bf092020-08-01 14:05:17 +000033HOST_PORT = 2222
BjornMagnussonXA80a92002020-03-19 14:31:06 +010034
35# Metrics vars
36cntr_msg_callbacks=0
37cntr_msg_fetched=0
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010038cntr_callbacks={}
BjornMagnussonXA80a92002020-03-19 14:31:06 +010039
40# Request and response constants
41CALLBACK_URL="/callbacks/<string:id>"
42APP_READ_URL="/get-event/<string:id>"
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010043APP_READ_ALL_URL="/get-all-events/<string:id>"
44DUMP_ALL_URL="/db"
BjornMagnussonXA80a92002020-03-19 14:31:06 +010045
46MIME_TEXT="text/plain"
47MIME_JSON="application/json"
48CAUGHT_EXCEPTION="Caught exception: "
49SERVER_ERROR="Server error :"
50
51#I'm alive function
52@app.route('/',
53 methods=['GET'])
54def index():
55 return 'OK', 200
56
57### Callback interface, for control
58
59# Fetch the oldest callback message for an id
60# URI and parameter, (GET): /get-event/<id>
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010061# response: message + 200 or just 204 or just 500(error)
BjornMagnussonXA80a92002020-03-19 14:31:06 +010062@app.route(APP_READ_URL,
63 methods=['GET'])
64def receiveresponse(id):
65 global msg_callbacks
66 global cntr_msg_fetched
67
68 try:
69 if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
70 cntr_msg_fetched+=1
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010071 cntr_callbacks[id][1]+=1
72 msg=msg_callbacks[id][0]
73 print("Fetching msg for id: "+id+", msg="+str(msg))
BjornMagnussonXA80a92002020-03-19 14:31:06 +010074 del msg_callbacks[id][0]
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010075 return json.dumps(msg),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +010076 print("No messages for id: "+id)
77 except Exception as e:
78 print(CAUGHT_EXCEPTION+str(e))
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010079 traceback.print_exc()
80 return "",500
BjornMagnussonXA80a92002020-03-19 14:31:06 +010081
82 return "",204
83
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +010084# Fetch all callback message for an id in an array
85# URI and parameter, (GET): /get-all-events/<id>
86# response: message + 200 or just 500(error)
87@app.route(APP_READ_ALL_URL,
88 methods=['GET'])
89def receiveresponse_all(id):
90 global msg_callbacks
91 global cntr_msg_fetched
92
93 try:
94 if ((id in msg_callbacks.keys()) and (len(msg_callbacks[id]) > 0)):
95 cntr_msg_fetched+=len(msg_callbacks[id])
96 cntr_callbacks[id][1]+=len(msg_callbacks[id])
97 msg=msg_callbacks[id]
98 print("Fetching all msgs for id: "+id+", msg="+str(msg))
99 del msg_callbacks[id]
100 return json.dumps(msg),200
101 print("No messages for id: "+id)
102 except Exception as e:
103 print(CAUGHT_EXCEPTION+str(e))
104 traceback.print_exc()
105 return "",500
106
107 msg=[]
108 return json.dumps(msg),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100109
110# Receive a callback message
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100111# URI and payload, (PUT or POST): /callbacks/<id> <json messages>
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100112# response: OK 200 or 500 for other errors
113@app.route(CALLBACK_URL,
114 methods=['PUT','POST'])
115def events_write(id):
116 global msg_callbacks
117 global cntr_msg_callbacks
118
119 try:
120 print("Received callback for id: "+id +", content-type="+request.content_type)
121 try:
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100122 if (request.content_type == MIME_JSON):
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100123 data = request.data
124 msg = json.loads(data)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100125 print("Payload(json): "+str(msg))
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100126 else:
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100127 msg={}
128 print("Payload(content-type="+request.content_type+"). Setting empty json as payload")
129 except Exception as e:
130 msg={}
131 print("(Exception) Payload does not contain any json, setting empty json as payload")
132 traceback.print_exc()
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100133
134 cntr_msg_callbacks += 1
135 if (id in msg_callbacks.keys()):
136 msg_callbacks[id].append(msg)
137 else:
138 msg_callbacks[id]=[]
139 msg_callbacks[id].append(msg)
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100140
141 if (id in cntr_callbacks.keys()):
142 cntr_callbacks[id][0] += 1
143 else:
144 cntr_callbacks[id]=[]
145 cntr_callbacks[id].append(1)
146 cntr_callbacks[id].append(0)
147
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100148 except Exception as e:
149 print(CAUGHT_EXCEPTION+str(e))
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100150 traceback.print_exc()
151 return 'NOTOK',500
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100152
153 return 'OK',200
154
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100155### Functions for test ###
156
157# Dump the whole db of current callbacks
158# URI and parameter, (GET): /db
159# response: message + 200
160@app.route(DUMP_ALL_URL,
161 methods=['GET'])
162def dump_db():
163 return json.dumps(msg_callbacks),200
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100164
165### Functions for metrics read out ###
166
167@app.route('/counter/received_callbacks',
168 methods=['GET'])
169def requests_submitted():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100170 req_id = request.args.get('id')
171 if (req_id is None):
172 return Response(str(cntr_msg_callbacks), status=200, mimetype=MIME_TEXT)
173
174 if (req_id in cntr_callbacks.keys()):
175 return Response(str(cntr_callbacks[req_id][0]), status=200, mimetype=MIME_TEXT)
176 else:
177 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100178
179@app.route('/counter/fetched_callbacks',
180 methods=['GET'])
181def requests_fetched():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100182 req_id = request.args.get('id')
183 if (req_id is None):
184 return Response(str(cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
185
186 if (req_id in cntr_callbacks.keys()):
187 return Response(str(cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
188 else:
189 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100190
191@app.route('/counter/current_messages',
192 methods=['GET'])
193def current_messages():
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100194 req_id = request.args.get('id')
195 if (req_id is None):
196 return Response(str(cntr_msg_callbacks-cntr_msg_fetched), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100197
BjornMagnussonXA49f0e5a2020-11-08 22:41:39 +0100198 if (req_id in cntr_callbacks.keys()):
199 return Response(str(cntr_callbacks[req_id][0]-cntr_callbacks[req_id][1]), status=200, mimetype=MIME_TEXT)
200 else:
201 return Response(str("0"), status=200, mimetype=MIME_TEXT)
BjornMagnussonXA80a92002020-03-19 14:31:06 +0100202
203
204### Admin ###
205
206# Reset all messsages and counters
207@app.route('/reset',
208 methods=['GET', 'POST', 'PUT'])
209def reset():
210 global msg_callbacks
211 global cntr_msg_fetched
212 global cntr_msg_callbacks
213
214 msg_callbacks={}
215 cntr_msg_fetched=0
216 cntr_msg_callbacks=0
217
218 return Response('OK', status=200, mimetype=MIME_TEXT)
219
220### Main function ###
221
222if __name__ == "__main__":
223 app.run(port=HOST_PORT, host=HOST_IP)