Generate mock pred message with one cell having better xput
[ric-app/qp.git] / qp / main.py
1 # ==================================================================================
2 #       Copyright (c) 2020 AT&T Intellectual Property.
3 #
4 #   Licensed under the Apache License, Version 2.0 (the "License");
5 #   you may not use this file except in compliance with the License.
6 #   You may obtain a copy of the License at
7 #
8 #          http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #   Unless required by applicable law or agreed to in writing, software
11 #   distributed under the License is distributed on an "AS IS" BASIS,
12 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 #   See the License for the specific language governing permissions and
14 #   limitations under the License.
15 # ==================================================================================
16 """
17 mock qp module
18
19 RMR Messages:
20  #define TS_QOE_PRED_REQ 30001
21  #define TS_QOE_PREDICTION 30002
22 30001 is the message type QP receives from the driver;
23 sends out type 30002 which should be routed to TS.
24
25 """
26
27 import json
28 import os
29 from mdclogpy import Logger
30 from ricxappframe.xapp_frame import RMRXapp, rmr
31
32 # pylint: disable=invalid-name
33 qp_xapp = None
34 logger = Logger(name=__name__)
35
36
37 def post_init(self):
38     """
39     Function that runs when xapp initialization is complete
40     """
41     self.predict_requests = 0
42     logger.debug("QP xApp started")
43
44
45 def qp_default_handler(self, summary, sbuf):
46     """
47     Function that processes messages for which no handler is defined
48     """
49     logger.debug("default handler received message type {}".format(summary[rmr.RMR_MS_MSG_TYPE]))
50     # we don't use rts here; free this
51     self.rmr_free(sbuf)
52
53
54 def qp_predict_handler(self, summary, sbuf):
55     """
56     Function that processes messages for type 30001
57     """
58     logger.debug("predict handler received message type {}".format(summary[rmr.RMR_MS_MSG_TYPE]))
59     logger.debug("adding somethign")
60     logger.debug("message is " + summary[rmr.RMR_MS_PAYLOAD].decode())
61     pred_req_msg = json.loads(summary[rmr.RMR_MS_PAYLOAD].decode())
62     all_cells = {}
63     ind = 0
64     for ncell in pred_req_msg["CellMeasurements"]:
65         if (ind == 0):
66             all_cells[ncell["CellID"]] = [50000, 20000]
67         else:
68             all_cells[ncell["CellID"]] = [20000, 10000]
69         ind += 1
70
71     pred_msg = {}
72     pred_msg[pred_req_msg["PredictionUE"]] = all_cells
73     self.predict_requests += 1
74     # we don't use rts here; free this
75     self.rmr_free(sbuf)
76     # send a mock message based on input
77     success = self.rmr_send(json.dumps(pred_msg).encode(), 30002)
78     if success:
79         logger.debug("predict handler: sent message successfully")
80     else:
81         logger.warning("predict handler: failed to send message")
82
83
84 def start(thread=False):
85     """
86     This is a convenience function that allows this xapp to run in Docker
87     for "real" (no thread, real SDL), but also easily modified for unit testing
88     (e.g., use_fake_sdl). The defaults for this function are for the Dockerized xapp.
89     """
90     logger.debug("QP xApp starting")
91     global qp_xapp
92     fake_sdl = os.environ.get("USE_FAKE_SDL", None)
93     qp_xapp = RMRXapp(qp_default_handler, rmr_port=4560, post_init=post_init, use_fake_sdl=bool(fake_sdl))
94     qp_xapp.register_callback(qp_predict_handler, 30001)
95     qp_xapp.run(thread)
96
97
98 def stop():
99     """
100     can only be called if thread=True when started
101     TODO: could we register a signal handler for Docker SIGTERM that calls this?
102     """
103     global qp_xapp
104     qp_xapp.stop()
105
106
107 def get_stats():
108     """
109     hacky for now, will evolve
110     """
111     global qp_xapp
112     return {"PredictRequests": qp_xapp.predict_requests}