d2c949bce7491386b4fdf624780fce5f3d65d010
[optf/osdf.git] / apps / slice_selection / optimizers / conductor / response_processor.py
1 # -------------------------------------------------------------------------
2 #   Copyright (C) 2020 Wipro Limited.
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 #
18
19 """
20 Module for processing response from conductor for slice selection
21 """
22
23 import re
24
25
26 class ResponseProcessor(object):
27     def __init__(self, request_info, slice_config):
28         self.request_info = request_info
29         self.slice_config = slice_config
30
31     def process_response(self, recommendations, model_info, subnets):
32         """Process conductor response to form the response for the API request
33
34             :param recommendations: recommendations from conductor
35             :param model_info: model info from the request
36             :param subnets: list of subnets
37             :return: response json as a dictionary
38         """
39         if not recommendations:
40             return self.get_slice_selection_response([])
41         model_name = model_info['name']
42         solutions = [self.get_solution_from_candidate(rec[model_name]['candidate'], model_info, subnets)
43                      for rec in recommendations]
44         return self.get_slice_selection_response(solutions)
45
46     def get_solution_from_candidate(self, candidate, model_info, subnets):
47         if candidate['inventory_type'] == 'nssi':
48             return {
49                 'UUID': model_info['UUID'],
50                 'invariantUUID': model_info['invariantUUID'],
51                 'NSSIName': candidate['instance_name'],
52                 'NSSIId': candidate['instance_id']
53             }
54
55         elif candidate['inventory_type'] == 'nsi':
56             return {
57                 'existingNSI': True,
58                 'sharedNSISolution': {
59                     'UUID': model_info['UUID'],
60                     'invariantUUID': model_info['invariantUUID'],
61                     'NSIName': candidate['instance_name'],
62                     'NSIId': candidate['instance_id']
63                 }
64             }
65
66         elif candidate['inventory_type'] == 'slice_profiles':
67             return {
68                 'existingNSI': False,
69                 'newNSISolution': {
70                     'sliceProfiles': self.get_slice_profiles_from_candidate(candidate, subnets)
71                 }
72             }
73
74     def get_slice_profiles_from_candidate(self, candidate, subnets):
75         slice_profiles = []
76         for subnet in subnets:
77             slice_profile = {self.get_profile_attribute(k, subnet): v for k, v in candidate.items()
78                              if k.startswith(subnet)}
79             slice_profile['domainType'] = subnet
80             slice_profiles.append(slice_profile)
81         return slice_profiles
82
83     def get_profile_attribute(self, attribute, subnet):
84         snake_to_camel = self.slice_config['attribute_mapping']['snake_to_camel']
85         return snake_to_camel[re.sub(f'^{subnet}_', '', attribute)]
86
87     def process_error_response(self, error_message):
88         """Form response message from the error message
89
90             :param error_message: error message while processing the request
91             :return: response json as dictionary
92         """
93         return {'requestId': self.request_info['requestId'],
94                 'transactionId': self.request_info['transactionId'],
95                 'requestStatus': 'error',
96                 'statusMessage': error_message}
97
98     def get_slice_selection_response(self, solutions):
99         """Get NSI selection response from final solution
100
101             :param solutions: final solutions
102             :return: NSI selection response to send back as dictionary
103         """
104         return {'requestId': self.request_info['requestId'],
105                 'transactionId': self.request_info['transactionId'],
106                 'requestStatus': 'completed',
107                 'statusMessage': '',
108                 'solutions': solutions}