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