Add DME integration
[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                 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYFAILED);
100             }
101             return deployState;
102         } catch (JsonProcessingException e) {
103             logger.warn("Failed to deploy SME functions for Rapp {}", rapp.getName(), e);
104         }
105         return false;
106     }
107
108     @Override
109     public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
110         logger.debug("Undeploying SME functions for Rapp {}", rapp.getName());
111         try {
112             rappInstance.getSme().getInvokerIds().forEach(this::deleteInvoker);
113             rappInstance.getSme().getServiceApiIds()
114                     .forEach(s -> deletePublishApi(s, rappInstance.getSme().getApfId()));
115             rappInstance.getSme().getProviderFunctionIds().forEach(this::deleteProviderFunc);
116             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYED);
117             return true;
118         } catch (Exception e) {
119             logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName(), e);
120         }
121         return false;
122     }
123
124     @Override
125     public boolean primeRapp(Rapp rapp) {
126         //If there is any priming operations on SME
127         return true;
128     }
129
130     @Override
131     public boolean deprimeRapp(Rapp rapp) {
132         //If there is any depriming operations
133         return true;
134     }
135
136     boolean createProviderDomain(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
137         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
138         try {
139             String providerDomainPayload =
140                     rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappInstance.getSme());
141             logger.debug("Provider domain payload {}", providerDomainPayload);
142             if (providerDomainPayload != null) {
143                 APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
144                         objectMapper.readValue(providerDomainPayload, APIProviderEnrolmentDetails.class);
145                 apiProviderEnrolmentDetails.setRegSec(
146                         apiProviderEnrolmentDetails.getRegSec() + rappInstance.getRappInstanceId());
147                 APIProviderEnrolmentDetails responseApiEnrollmentDetails =
148                         providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
149                 if (responseApiEnrollmentDetails.getApiProvFuncs() != null) {
150                     rappInstance.getSme().setProviderFunctionIds(responseApiEnrollmentDetails.getApiProvFuncs().stream()
151                                                                          .map(APIProviderFunctionDetails::getApiProvFuncId)
152                                                                          .toList());
153
154                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
155                             ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
156                                                                                                      .setApfId(
157                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
158                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
159                             ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
160                                                                                                      .setAefId(
161                                                                                                              apiProviderFunctionDetails.getApiProvFuncId()));
162                     return true;
163                 }
164             }
165         } catch (Exception e) {
166             logger.warn("Error in creating provider domain", e);
167         }
168         return false;
169     }
170
171     Optional<APIProviderFunctionDetails> getProviderFuncId(List<APIProviderFunctionDetails> apiProviderFunctionDetails,
172             ApiProviderFuncRole apiProviderFuncRole) {
173         return apiProviderFunctionDetails.stream()
174                        .filter(apiProviderFunctionDetail -> apiProviderFunctionDetail.getApiProvFuncRole()
175                                                                     .equals(apiProviderFuncRole)).findFirst();
176     }
177
178     void deleteProviderFunc(String registrationId) {
179         providerDefaultApiClient.deleteRegistrationsRegistrationId(registrationId);
180     }
181
182
183     boolean createPublishApi(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
184         logger.debug("Creating publish api for Rapp {}", rapp.getName());
185         try {
186             String providerApiPayload =
187                     rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappInstance.getSme());
188             if (providerApiPayload != null) {
189                 ServiceAPIDescription serviceAPIDescription =
190                         objectMapper.readValue(providerApiPayload, ServiceAPIDescription.class);
191                 serviceAPIDescription.getAefProfiles()
192                         .forEach(aefProfile -> aefProfile.setAefId(rappInstance.getSme().getAefId()));
193                 ServiceAPIDescription serviceAPIDescriptionResponse =
194                         publishServiceDefaultApiClient.postApfIdServiceApis(rappInstance.getSme().getApfId(),
195                                 serviceAPIDescription);
196
197                 if (serviceAPIDescriptionResponse.getAefProfiles() != null) {
198                     rappInstance.getSme().setServiceApiIds(List.of(serviceAPIDescriptionResponse.getApiId()));
199                     return true;
200                 }
201             }
202         } catch (Exception e) {
203             logger.warn("Error in creating publish api", e);
204         }
205         return false;
206     }
207
208     void deletePublishApi(String serviceApiId, String apfId) {
209         publishServiceDefaultApiClient.deleteApfIdServiceApisServiceApiId(serviceApiId, apfId);
210     }
211
212     boolean createInvoker(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
213         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
214         try {
215             String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappInstance.getSme());
216             if (invokerPayload != null) {
217                 List<APIInvokerEnrolmentDetails> apiInvokerEnrolmentDetails =
218                         objectMapper.readValue(invokerPayload, new TypeReference<>() { });
219                 apiInvokerEnrolmentDetails.forEach(apiInvokerEnrolmentDetail -> {
220                     APIInvokerEnrolmentDetails apiInvokerEnrolmentDetailsResponse =
221                             invokerDefaultApiClient.postOnboardedInvokers(apiInvokerEnrolmentDetail);
222                     if (apiInvokerEnrolmentDetailsResponse.getApiList() != null) {
223                         rappInstance.getSme()
224                                 .setInvokerIds(List.of(apiInvokerEnrolmentDetailsResponse.getApiInvokerId()));
225                     }
226                 });
227                 return true;
228             }
229         } catch (Exception e) {
230             logger.warn("Error in creating invoker", e);
231         }
232         return false;
233     }
234
235     void deleteInvoker(String invokerId) {
236         invokerDefaultApiClient.deleteOnboardedInvokersOnboardingId(invokerId);
237     }
238 }