My first commit
[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  * Copyright (C) 2024 OpenInfra Foundation Europe. All rights reserved.
5  * ===============================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  * ============LICENSE_END========================================================================
18  */
19
20 package com.oransc.rappmanager.sme.service;
21
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         if (rappInstance.isSMEEnabled()) {
93             if ((rappInstance.getSme().getProviderFunction() == null || createProviderDomain(rapp, rappInstance)) && (
94                     rappInstance.getSme().getServiceApis() == null || createPublishApi(rapp, rappInstance)) && (
95                     rappInstance.getSme().getInvokers() == null || createInvoker(rapp, rappInstance))) {
96                 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYED);
97                 return true;
98             }
99             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYFAILED);
100             rappInstance.setReason("Unable to deploy SME");
101             return false;
102         }
103         return true;
104     }
105
106     @Override
107     public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
108         logger.debug("Undeploying SME functions for Rapp {}", rapp.getName());
109         if (rappInstance.isSMEEnabled()) {
110             try {
111                 Optional.ofNullable(rappInstance.getSme().getInvokerIds())
112                         .ifPresent(invokerList -> invokerList.forEach(this::deleteInvoker));
113                 Optional.ofNullable(rappInstance.getSme().getServiceApiIds()).ifPresent(
114                         serviceApiList -> serviceApiList.forEach(
115                                 s -> deletePublishApi(s, rappInstance.getSme().getApfId())));
116                 Optional.ofNullable(rappInstance.getSme().getProviderFunctionIds())
117                         .ifPresent(providerList -> providerList.forEach(this::deleteProviderFunc));
118                 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYED);
119                 return true;
120             } catch (Exception e) {
121                 logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName(), e);
122             }
123             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYFAILED);
124             rappInstance.setReason("Unable to undeploy SME");
125             return false;
126         }
127         return true;
128     }
129
130     @Override
131     public boolean primeRapp(Rapp rapp) {
132         //If there is any priming operations on SME
133         return true;
134     }
135
136     @Override
137     public boolean deprimeRapp(Rapp rapp) {
138         //If there is any depriming operations
139         return true;
140     }
141
142     boolean createProviderDomain(Rapp rapp, RappInstance rappInstance) {
143         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
144         try {
145             String providerDomainPayload =
146                     rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappInstance.getSme());
147             logger.debug("Provider domain payload {}", providerDomainPayload);
148             if (providerDomainPayload != null) {
149                 APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
150                         objectMapper.readValue(providerDomainPayload, APIProviderEnrolmentDetails.class);
151                 apiProviderEnrolmentDetails.setRegSec(
152                         apiProviderEnrolmentDetails.getRegSec() + rappInstance.getRappInstanceId());
153                 APIProviderEnrolmentDetails responseApiEnrollmentDetails =
154                         providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
155                 if (responseApiEnrollmentDetails.getApiProvFuncs() != null) {
156                     rappInstance.getSme().setProviderFunctionIds(responseApiEnrollmentDetails.getApiProvFuncs().stream()
157                                                                          .map(APIProviderFunctionDetails::getApiProvFuncId)
158                                                                          .toList());
159
160                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
161                             ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
162                                                                                                      .setApfId(
163                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
164                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
165                             ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
166                                                                                                      .setAefId(
167                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
168                     return true;
169                 }
170             }
171         } catch (Exception e) {
172             logger.warn("Error in creating provider domain", e);
173         }
174         return false;
175     }
176
177     Optional<APIProviderFunctionDetails> getProviderFuncId(List<APIProviderFunctionDetails> apiProviderFunctionDetails,
178             ApiProviderFuncRole apiProviderFuncRole) {
179         return apiProviderFunctionDetails.stream()
180                        .filter(apiProviderFunctionDetail -> apiProviderFunctionDetail.getApiProvFuncRole()
181                                                                     .equals(apiProviderFuncRole)).findFirst();
182     }
183
184     void deleteProviderFunc(String registrationId) {
185         providerDefaultApiClient.deleteRegistrationsRegistrationId(registrationId);
186     }
187
188
189     boolean createPublishApi(Rapp rapp, RappInstance rappInstance) {
190         logger.debug("Creating publish api for Rapp {}", rapp.getName());
191         try {
192             String providerApiPayload =
193                     rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappInstance.getSme());
194             if (providerApiPayload != null) {
195                 ServiceAPIDescription serviceAPIDescription =
196                         objectMapper.readValue(providerApiPayload, ServiceAPIDescription.class);
197                 serviceAPIDescription.getAefProfiles()
198                         .forEach(aefProfile -> aefProfile.setAefId(rappInstance.getSme().getAefId()));
199                 ServiceAPIDescription serviceAPIDescriptionResponse =
200                         publishServiceDefaultApiClient.postApfIdServiceApis(rappInstance.getSme().getApfId(),
201                                 serviceAPIDescription);
202
203                 if (serviceAPIDescriptionResponse.getAefProfiles() != null) {
204                     rappInstance.getSme().setServiceApiIds(List.of(serviceAPIDescriptionResponse.getApiId()));
205                     return true;
206                 }
207             }
208         } catch (Exception e) {
209             logger.warn("Error in creating publish api", e);
210         }
211         return false;
212     }
213
214     void deletePublishApi(String serviceApiId, String apfId) {
215         publishServiceDefaultApiClient.deleteApfIdServiceApisServiceApiId(serviceApiId, apfId);
216     }
217
218     boolean createInvoker(Rapp rapp, RappInstance rappInstance) {
219         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
220         try {
221             String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappInstance.getSme());
222             if (invokerPayload != null) {
223                 List<APIInvokerEnrolmentDetails> apiInvokerEnrolmentDetails =
224                         objectMapper.readValue(invokerPayload, new TypeReference<>() { });
225                 apiInvokerEnrolmentDetails.forEach(apiInvokerEnrolmentDetail -> {
226                     APIInvokerEnrolmentDetails apiInvokerEnrolmentDetailsResponse =
227                             invokerDefaultApiClient.postOnboardedInvokers(apiInvokerEnrolmentDetail);
228                     if (apiInvokerEnrolmentDetailsResponse.getApiList() != null) {
229                         rappInstance.getSme()
230                                 .setInvokerIds(List.of(apiInvokerEnrolmentDetailsResponse.getApiInvokerId()));
231                     }
232                 });
233                 return true;
234             }
235         } catch (Exception e) {
236             logger.warn("Error in creating invoker", e);
237         }
238         return false;
239     }
240
241     void deleteInvoker(String invokerId) {
242         invokerDefaultApiClient.deleteOnboardedInvokersOnboardingId(invokerId);
243     }
244 }