Fix for NSI selection response
[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, model_type):
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             :param model_type: NSI or NSSI
38             :return: response json as a dictionary
39         """
40         if not recommendations:
41             return self.get_slice_selection_response([])
42         model_name = model_info['name']
43         solutions = [self.get_solution_from_candidate(rec[model_name]['candidate'], model_info, subnets, model_type)
44                      for rec in recommendations]
45         return self.get_slice_selection_response(solutions)
46
47     def get_solution_from_candidate(self, candidate, model_info, subnets, model_type):
48         if candidate['inventory_type'] == 'slice_profiles':
49             return {
50                 'existingNSI': False,
51                 'newNSISolution': {
52                     'sliceProfiles': self.get_slice_profiles_from_candidate(candidate, subnets)
53                 }
54             }
55         elif model_type == 'NSSI':
56             return {
57                 'UUID': model_info['UUID'],
58                 'invariantUUID': model_info['invariantUUID'],
59                 'NSSIName': candidate['instance_name'],
60                 'NSSIId': candidate['instance_id']
61             }
62
63         elif model_type == 'NSI':
64             return {
65                 'existingNSI': True,
66                 'sharedNSISolution': {
67                     'UUID': model_info['UUID'],
68                     'invariantUUID': model_info['invariantUUID'],
69                     'NSIName': candidate['instance_name'],
70                     'NSIId': candidate['instance_id']
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}