Merge "Fix main manifest attribute in rAPP Catalogue"
[nonrtric.git] / test / cr / app / cr.py
1
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
19 from flask import Flask, request, Response
20 from time import sleep
21 import time
22 from datetime import datetime
23 import json
24 import traceback
25 import logging
26
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())
31
32 log = logging.getLogger('werkzeug')
33 log.addFilter(AjaxFilter())
34
35 app = Flask(__name__)
36
37 # list of callback messages
38 msg_callbacks={}
39
40 # Server info
41 HOST_IP = "::"
42 HOST_PORT = 2222
43
44 # Metrics vars
45 cntr_msg_callbacks=0
46 cntr_msg_fetched=0
47 cntr_callbacks={}
48
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>"
53 DUMP_ALL_URL="/db"
54
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"
60
61 #I'm alive function
62 @app.route('/',
63     methods=['GET'])
64 def 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>
71 # response: message + 200 or just 204 or just 500(error)
72 @app.route(APP_READ_URL,
73     methods=['GET'])
74 def 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
81             cntr_callbacks[id][1]+=1
82             msg=msg_callbacks[id][0]
83             print("Fetching msg for id: "+id+", msg="+str(msg))
84             del msg[TIME_STAMP]
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))
90         traceback.print_exc()
91         return "",500
92
93     return "",204
94
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,
99     methods=['GET'])
100 def 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))
110             for sub_msg in 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()
118         return "",500
119
120     msg=[]
121     return json.dumps(msg),200
122
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):
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:
135             if (request.content_type == MIME_JSON):
136                 data = request.data
137                 msg = json.loads(data)
138                 print("Payload(json): "+str(msg))
139             else:
140                 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()
146
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)
151         else:
152             msg_callbacks[id]=[]
153             msg_callbacks[id].append(msg)
154
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
162     except Exception as e:
163         print(CAUGHT_EXCEPTION+str(e))
164         traceback.print_exc()
165         return 'NOTOK',500
166
167     return 'OK',200
168
169 ### 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'])
176 def dump_db():
177     return json.dumps(msg_callbacks),200
178
179 ### Functions for metrics read out ###
180
181 @app.route('/counter/received_callbacks',
182     methods=['GET'])
183 def requests_submitted():
184     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)
192
193 @app.route('/counter/fetched_callbacks',
194     methods=['GET'])
195 def requests_fetched():
196     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)
204
205 @app.route('/counter/current_messages',
206     methods=['GET'])
207 def current_messages():
208     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)
211
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)
214     else:
215         return Response(str("0"), status=200, mimetype=MIME_TEXT)
216
217
218 ### Admin ###
219
220 # Reset all messsages and counters
221 @app.route('/reset',
222     methods=['GET', 'POST', 'PUT'])
223 def reset():
224     global msg_callbacks
225     global cntr_msg_fetched
226     global cntr_msg_callbacks
227     global cntr_callbacks
228
229     msg_callbacks={}
230     cntr_msg_fetched=0
231     cntr_msg_callbacks=0
232     cntr_callbacks={}
233
234     return Response('OK', status=200, mimetype=MIME_TEXT)
235
236 ### Main function ###
237
238 if __name__ == "__main__":
239     app.run(port=HOST_PORT, host=HOST_IP)