blob: d3fed3ad285f11f9890672346eda97567b7fb537 [file] [log] [blame]
elinuxhenrik233225c2020-04-28 15:31:33 +02001# ============LICENSE_START===============================================
2# Copyright (C) 2020 Nordix Foundation. All rights reserved.
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# ============LICENSE_END=================================================
16#
17
18import argparse
19from datetime import datetime
20from pygments.util import xrange
21from requests import ConnectionError
22import requests
23import sys
24import threading
25import time
26
27SERVICE_NAME = 'HealthCheck'
28BASE_URL = 'http://localhost:8081'
29RIC_CHUNK_SIZE = 10
30TIME_BETWEEN_CHECKS = 60
31
32type_to_use = ''
33policy_body = ''
34
35
36class Ric:
37
38 def __init__(self, name, supported_types, state):
39 self.name = name
40 self.supports_type_to_use = self.policy_type_supported(supported_types)
41 self.state = state
42 self.no_of_created_policies = 0
43 self.no_of_read_policies = 0
44 self.no_of_updated_policies = 0
45 self.no_of_deleted_policies = 0
46
47 def update_supported_types(self, supported_types):
48 self.supports_type_to_use = self.policy_type_supported(supported_types)
49
50 def policy_type_supported(self, supported_policy_types):
51 for supported_type in supported_policy_types:
52 if type_to_use == supported_type:
53 return True
54
55 return False
56
57
58class PolicyCheckThread (threading.Thread):
59
60 def __init__(self, thread_id, ric):
61 threading.Thread.__init__(self)
62 self.thread_id = thread_id
63 self.ric = ric
64
65 def run(self):
66 verboseprint(f'Checking ric: {self.ric.name}')
67 if put_policy(self.thread_id, self.ric.name):
68 verboseprint(f'Created policy: {self.thread_id} in ric: {self.ric.name}')
69 self.ric.no_of_created_policies += 1
70 time.sleep(0.5)
71 if get_policy(self.thread_id):
72 verboseprint(f'Read policy: {self.thread_id} from ric: {self.ric.name}')
73 self.ric.no_of_read_policies += 1
74 if put_policy(self.thread_id, self.ric.name, update_value=1):
75 verboseprint(f'Updated policy: {self.thread_id} in ric: {self.ric.name}')
76 self.ric.no_of_updated_policies += 1
77 if delete_policy(self.thread_id):
78 verboseprint(f'Deleted policy: {self.thread_id} from ric: {self.ric.name}')
79 self.ric.no_of_deleted_policies += 1
80
81
82def get_rics_from_agent():
83 resp = requests.get(BASE_URL + '/rics')
84 if not resp.ok:
85 verboseprint(f'Unable to get Rics {resp.status_code}')
86 return {}
87 return resp.json()
88
89
90def create_ric_dict(rics_as_json):
91 rics = {}
92 for ric_info in rics_as_json:
93 rics[ric_info["ricName"]] = (Ric(ric_info["ricName"], ric_info["policyTypes"], ric_info['state']))
94 verboseprint(f'Adding ric: {rics[ric_info["ricName"]]}')
95
96 return rics
97
98
99def update_rics():
100 added_rics = {}
101 for ric_info in get_rics_from_agent():
102 if ric_info["ricName"] in rics:
103 rics[ric_info["ricName"]].update_supported_types(ric_info["policyTypes"])
104 rics[ric_info["ricName"]].state = ric_info['state']
105 else:
106 added_rics[ric_info["ricName"]] = (Ric(ric_info["ricName"], ric_info["policyTypes"]))
107 verboseprint(f'Adding ric: {rics[ric_info["ricName"]]}')
108
109 rics.update(added_rics)
110
111
112def put_policy(thread_id, ric_name, update_value=0):
113 policy_id = f'thread_{thread_id}'
114 complete_url = f'{BASE_URL}/policy?type={type_to_use}&id={policy_id}&ric={ric_name}&service={SERVICE_NAME}'
115 headers = {'content-type': 'application/json'}
116 resp = requests.put(complete_url, policy_body.replace('XXX', str(thread_id + update_value)), headers=headers, verify=False)
117
118 if not resp.ok:
119 verboseprint(f'Unable to create policy {resp}')
120 return False
121 else:
122 return True
123
124
125def get_policy(thread_id):
126 policy_id = f'thread_{thread_id}'
127 complete_url = f'{BASE_URL}/policy?id={policy_id}'
128 resp = requests.get(complete_url)
129
130 if not resp.ok:
131 verboseprint(f'Unable to get policy {resp}')
132 return False
133 else:
134 return True
135
136
137def delete_policy(thread_id):
138 policy_id = f'thread_{thread_id}'
139 complete_url = f'{BASE_URL}/policy?id={policy_id}'
140 resp = requests.delete(complete_url)
141
142 if not resp.ok:
143 verboseprint(f'Unable to delete policy for policy ID {policy_id}')
144 return False
145
146 return True
147
148
149def statistics(duration):
150 no_of_unavailable_rics = 0
151 no_of_rics_not_supporting_type = 0
152 no_of_rics_supporting_type = 0
153 no_of_created_policies = 0
154 no_of_read_policies = 0
155 no_of_updated_policies = 0
156 no_of_deleted_policies = 0
157
158 for ric in rics.values():
159 if not (ric.state == 'AVAILABLE' or ric.state == 'CONSISTENCY_CHECK'):
160 no_of_unavailable_rics += 1
161 elif ric.supports_type_to_use:
162 no_of_rics_supporting_type += 1
163 no_of_created_policies += ric.no_of_created_policies
164 no_of_read_policies += ric.no_of_read_policies
165 no_of_updated_policies += ric.no_of_updated_policies
166 no_of_deleted_policies += ric.no_of_deleted_policies
167 else:
168 no_of_rics_not_supporting_type += 1
169
170 print(f'*********** Statistics {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} ***********')
171 print(f'Duration of check: {duration.total_seconds()} seconds')
172 print(f'Number of checks: {no_of_checks}')
173 print(f'Number of unavailable rics: {no_of_unavailable_rics}')
174 print(f'Number of rics not supporting type: {no_of_rics_not_supporting_type}')
175 print(f'Number of rics supporting type: {no_of_rics_supporting_type}')
176 print(f'Number of created policies: {no_of_created_policies}')
177 print(f'Number of read policies: {no_of_read_policies}')
178 print(f'Number of updated policies: {no_of_updated_policies}')
179 print(f'Number of deleted policies: {no_of_deleted_policies}')
180 print('******************************************************')
181
182
183def run_check_threads(rics):
184 thread_id = 1
185 threads = []
186 for ric in rics.values():
187 if ric.supports_type_to_use and (ric.state == 'AVAILABLE' or ric.state == 'CONSISTENCY_CHECK'): #or ric.name == 'ric_not_working':
188 policy_checker = PolicyCheckThread(thread_id, ric)
189 policy_checker.start()
190 thread_id += 1
191 threads.append(policy_checker)
192
193 for checker in threads:
194 checker.join()
195
196
197def split_rics_equally(chunks):
198 # prep with empty dicts
199 return_list = [dict() for _ in xrange(chunks)]
200 idx = 0
201 for k,v in rics.items():
202 return_list[idx][k] = v
203 if idx < chunks-1: # indexes start at 0
204 idx += 1
205 else:
206 idx = 0
207 return return_list
208
209
210def get_no_of_chunks(size_of_chunks, size_to_chunk):
211 (q, _) = divmod(size_to_chunk, size_of_chunks)
212 return q
213
214
215if __name__ == '__main__':
216 parser = argparse.ArgumentParser(prog='PROG')
217 parser.add_argument('policyTypeId', help='The ID of the policy type to use')
218 parser.add_argument('policyBodyPath', help='The path to the JSON body of the policy to create')
219 parser.add_argument('-v', '--verbose', action='store_true', help='Turn on verbose printing')
220 parser.add_argument('--version', action='version', version='%(prog)s 1.0')
221 args = vars(parser.parse_args())
222
223 if args['verbose']:
224 def verboseprint(*args, **kwargs):
225 print(*args, **kwargs)
226 else:
227 verboseprint = lambda *a, **k: None # do-nothing function
228
229 verboseprint(f'Using policy type {args["policyTypeId"]}')
230 verboseprint(f'Using policy file {args["policyBodyPath"]}')
231
232 type_to_use = args["policyTypeId"]
233 with open(args["policyBodyPath"]) as json_file:
234 policy_body = json_file.read()
235 verboseprint(f'Policy body: {policy_body}')
236
237 try:
238 rics_from_agent = get_rics_from_agent()
239 except ConnectionError:
240 print(f'Policy Agent is not answering on {BASE_URL}, cannot start!')
241 sys.exit(1)
242
243 rics = create_ric_dict(rics_from_agent)
244
245 no_of_checks = 0
246 while True:
247 start_time = datetime.now()
248 chunked_rics = split_rics_equally(get_no_of_chunks(RIC_CHUNK_SIZE, rics.__len__()))
249 for ric_chunk in chunked_rics:
250 run_check_threads(ric_chunk)
251
252 no_of_checks += 1
253 finish_time = datetime.now()
254 duration = finish_time - start_time
255 statistics(duration)
256 sleep_time = TIME_BETWEEN_CHECKS - duration.total_seconds()
257 verboseprint(f'Sleeping {sleep_time} seconds')
258 time.sleep(sleep_time)
259 update_rics()
260
261 verboseprint('Exiting main')