Add reason for rApp instance deploy/undeploy failure
[nonrtric/plt/rappmanager.git] / rapp-manager-sme / src / main / java / com / oransc / rappmanager / sme / service / SmeDeployer.java
1 /*-
2  * ============LICENSE_START======================================================================
3  * Copyright (C) 2023 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 package com.oransc.rappmanager.sme.service;
20
21 import com.fasterxml.jackson.core.JsonProcessingException;
22 import com.fasterxml.jackson.core.type.TypeReference;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.oransc.rappmanager.models.RappDeployer;
25 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
26 import com.oransc.rappmanager.models.rapp.Rapp;
27 import com.oransc.rappmanager.models.rapp.RappEvent;
28 import com.oransc.rappmanager.models.rappinstance.RappInstance;
29 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
30 import com.oransc.rappmanager.sme.invoker.data.APIInvokerEnrolmentDetails;
31 import com.oransc.rappmanager.sme.provider.data.APIProviderEnrolmentDetails;
32 import com.oransc.rappmanager.sme.provider.data.APIProviderFunctionDetails;
33 import com.oransc.rappmanager.sme.provider.data.ApiProviderFuncRole;
34 import com.oransc.rappmanager.sme.provider.data.RegistrationInformation;
35 import com.oransc.rappmanager.sme.publishservice.data.ServiceAPIDescription;
36 import java.util.List;
37 import java.util.Optional;
38 import lombok.RequiredArgsConstructor;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.stereotype.Service;
42
43 @Service
44 @RequiredArgsConstructor
45 public class SmeDeployer implements RappDeployer {
46
47     Logger logger = LoggerFactory.getLogger(SmeDeployer.class);
48
49     private final com.oransc.rappmanager.sme.provider.rest.DefaultApiClient providerDefaultApiClient;
50
51
52     private final com.oransc.rappmanager.sme.publishservice.rest.DefaultApiClient publishServiceDefaultApiClient;
53
54     private final com.oransc.rappmanager.sme.invoker.rest.DefaultApiClient invokerDefaultApiClient;
55
56     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
57
58     private final ObjectMapper objectMapper;
59
60     private final RappInstanceStateMachine rappInstanceStateMachine;
61
62     private String amfRegistrationId;
63
64
65     APIProviderEnrolmentDetails createAMF() {
66         APIProviderEnrolmentDetails responseApiEnrollmentDetails = null;
67         try {
68             APIProviderFunctionDetails apiProviderFunctionDetails = new APIProviderFunctionDetails();
69             apiProviderFunctionDetails.setApiProvFuncRole(ApiProviderFuncRole.AMF);
70             apiProviderFunctionDetails.setApiProvFuncInfo("Rapp Manager as AMF");
71             apiProviderFunctionDetails.setRegInfo(new RegistrationInformation().apiProvPubKey("asd"));
72
73             APIProviderEnrolmentDetails apiProviderEnrolmentDetails = new APIProviderEnrolmentDetails();
74             apiProviderEnrolmentDetails.setRegSec("PSK");
75             apiProviderEnrolmentDetails.setApiProvDomInfo("Rapp Manager as AMF");
76             apiProviderEnrolmentDetails.setApiProvFuncs(List.of(apiProviderFunctionDetails));
77             responseApiEnrollmentDetails = providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
78             amfRegistrationId = responseApiEnrollmentDetails.getApiProvDomId();
79         } catch (Exception e) {
80             logger.warn("Error in creating AMF", e);
81         }
82         return responseApiEnrollmentDetails;
83     }
84
85     void deleteAMF() {
86         deleteProviderFunc(amfRegistrationId);
87     }
88
89     @Override
90     public boolean deployRappInstance(Rapp rapp, RappInstance rappInstance) {
91         logger.debug("Deploying SME functions for RappInstance {}", rappInstance.getRappInstanceId());
92         try {
93             boolean deployState =
94                     createProviderDomain(rapp, rappInstance) && createPublishApi(rapp, rappInstance) && createInvoker(
95                             rapp, rappInstance);
96             if (deployState) {
97                 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYED);
98             } else {
99                 rappInstance.setReason("Unable to deploy SME");
100                 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYFAILED);
101             }
102             return deployState;
103         } catch (JsonProcessingException e) {
104             logger.warn("Failed to deploy SME functions for Rapp {}", rapp.getName(), e);
105         }
106         rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYFAILED);
107         rappInstance.setReason("Unable to deploy SME");
108         return false;
109     }
110
111     @Override
112     public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
113         logger.debug("Undeploying SME functions for Rapp {}", rapp.getName());
114         try {
115             rappInstance.getSme().getInvokerIds().forEach(this::deleteInvoker);
116             rappInstance.getSme().getServiceApiIds()
117                     .forEach(s -> deletePublishApi(s, rappInstance.getSme().getApfId()));
118             rappInstance.getSme().getProviderFunctionIds().forEach(this::deleteProviderFunc);
119             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYED);
120             return true;
121         } catch (Exception e) {
122             logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName(), e);
123         }
124         rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYFAILED);
125         rappInstance.setReason("Unable to undeploy SME");
126         return false;
127     }
128
129     @Override
130     public boolean primeRapp(Rapp rapp) {
131         //If there is any priming operations on SME
132         return true;
133     }
134
135     @Override
136     public boolean deprimeRapp(Rapp rapp) {
137         //If there is any depriming operations
138         return true;
139     }
140
141     boolean createProviderDomain(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
142         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
143         try {
144             String providerDomainPayload =
145                     rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappInstance.getSme());
146             logger.debug("Provider domain payload {}", providerDomainPayload);
147             if (providerDomainPayload != null) {
148                 APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
149                         objectMapper.readValue(providerDomainPayload, APIProviderEnrolmentDetails.class);
150                 apiProviderEnrolmentDetails.setRegSec(
151                         apiProviderEnrolmentDetails.getRegSec() + rappInstance.getRappInstanceId());
152                 APIProviderEnrolmentDetails responseApiEnrollmentDetails =
153                         providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
154                 if (responseApiEnrollmentDetails.getApiProvFuncs() != null) {
155                     rappInstance.getSme().setProviderFunctionIds(responseApiEnrollmentDetails.getApiProvFuncs().stream()
156                                                                          .map(APIProviderFunctionDetails::getApiProvFuncId)
157                                                                          .toList());
158
159                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
160                             ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
161                                                                                                      .setApfId(
162                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
163                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
164                             ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
165                                                                                                      .setAefId(
166                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
167                     return true;
168                 }
169             }
170         } catch (Exception e) {
171             logger.warn("Error in creating provider domain", e);
172         }
173         return false;
174     }
175
176     Optional<APIProviderFunctionDetails> getProviderFuncId(List<APIProviderFunctionDetails> apiProviderFunctionDetails,
177             ApiProviderFuncRole apiProviderFuncRole) {
178         return apiProviderFunctionDetails.stream()
179                        .filter(apiProviderFunctionDetail -> apiProviderFunctionDetail.getApiProvFuncRole()
180                                                                     .equals(apiProviderFuncRole)).findFirst();
181     }
182
183     void deleteProviderFunc(String registrationId) {
184         providerDefaultApiClient.deleteRegistrationsRegistrationId(registrationId);
185     }
186
187
188     boolean createPublishApi(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
189         logger.debug("Creating publish api for Rapp {}", rapp.getName());
190         try {
191             String providerApiPayload =
192                     rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappInstance.getSme());
193             if (providerApiPayload != null) {
194                 ServiceAPIDescription serviceAPIDescription =
195                         objectMapper.readValue(providerApiPayload, ServiceAPIDescription.class);
196                 serviceAPIDescription.getAefProfiles()
197                         .forEach(aefProfile -> aefProfile.setAefId(rappInstance.getSme().getAefId()));
198                 ServiceAPIDescription serviceAPIDescriptionResponse =
199                         publishServiceDefaultApiClient.postApfIdServiceApis(rappInstance.getSme().getApfId(),
200                                 serviceAPIDescription);
201
202                 if (serviceAPIDescriptionResponse.getAefProfiles() != null) {
203                     rappInstance.getSme().setServiceApiIds(List.of(serviceAPIDescriptionResponse.getApiId()));
204                     return true;
205                 }
206             }
207         } catch (Exception e) {
208             logger.warn("Error in creating publish api", e);
209         }
210         return false;
211     }
212
213     void deletePublishApi(String serviceApiId, String apfId) {
214         publishServiceDefaultApiClient.deleteApfIdServiceApisServiceApiId(serviceApiId, apfId);
215     }
216
217     boolean createInvoker(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
218         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
219         try {
220             String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappInstance.getSme());
221             if (invokerPayload != null) {
222                 List<APIInvokerEnrolmentDetails> apiInvokerEnrolmentDetails =
223                         objectMapper.readValue(invokerPayload, new TypeReference<>() { });
224                 apiInvokerEnrolmentDetails.forEach(apiInvokerEnrolmentDetail -> {
225                     APIInvokerEnrolmentDetails apiInvokerEnrolmentDetailsResponse =
226                             invokerDefaultApiClient.postOnboardedInvokers(apiInvokerEnrolmentDetail);
227                     if (apiInvokerEnrolmentDetailsResponse.getApiList() != null) {
228                         rappInstance.getSme()
229                                 .setInvokerIds(List.of(apiInvokerEnrolmentDetailsResponse.getApiInvokerId()));
230                     }
231                 });
232                 return true;
233             }
234         } catch (Exception e) {
235             logger.warn("Error in creating invoker", e);
236         }
237         return false;
238     }
239
240     void deleteInvoker(String invokerId) {
241         invokerDefaultApiClient.deleteOnboardedInvokersOnboardingId(invokerId);
242     }
243 }