Add initial version of code
[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;
25 import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
26 import com.oransc.rappmanager.models.RappDeployer;
27 import com.oransc.rappmanager.models.RappEvent;
28 import com.oransc.rappmanager.models.cache.RappCacheService;
29 import com.oransc.rappmanager.models.statemachine.RappStateMachine;
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.AefProfile;
36 import com.oransc.rappmanager.sme.publishservice.data.ServiceAPIDescription;
37 import java.util.List;
38 import java.util.Optional;
39 import java.util.stream.Collectors;
40 import lombok.RequiredArgsConstructor;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.stereotype.Service;
44
45 @Service
46 @RequiredArgsConstructor
47 public class SmeDeployer implements RappDeployer {
48
49     Logger logger = LoggerFactory.getLogger(SmeDeployer.class);
50
51     private final com.oransc.rappmanager.sme.provider.rest.DefaultApiClient providerDefaultApiClient;
52
53     private final com.oransc.rappmanager.sme.publishservice.rest.DefaultApiClient publishServiceDefaultApiClient;
54
55     private final com.oransc.rappmanager.sme.invoker.rest.DefaultApiClient invokerDefaultApiClient;
56
57     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
58
59     private final ObjectMapper objectMapper;
60
61     private final RappCacheService rappCacheService;
62
63     private final RappStateMachine rappStateMachine;
64
65     private String amfRegistrationId;
66
67
68     APIProviderEnrolmentDetails createAMF() {
69         APIProviderEnrolmentDetails responseApiEnrollmentDetails = null;
70         try {
71             APIProviderFunctionDetails apiProviderFunctionDetails = new APIProviderFunctionDetails();
72             apiProviderFunctionDetails.setApiProvFuncRole(ApiProviderFuncRole.AMF);
73             apiProviderFunctionDetails.setApiProvFuncInfo("Rapp Manager as AMF");
74             apiProviderFunctionDetails.setRegInfo(new RegistrationInformation().apiProvPubKey("asd"));
75
76             APIProviderEnrolmentDetails apiProviderEnrolmentDetails = new APIProviderEnrolmentDetails();
77             apiProviderEnrolmentDetails.setRegSec("PSK");
78             apiProviderEnrolmentDetails.setApiProvDomInfo("Rapp Manager as AMF");
79             apiProviderEnrolmentDetails.setApiProvFuncs(List.of(apiProviderFunctionDetails));
80             responseApiEnrollmentDetails = providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
81             amfRegistrationId = responseApiEnrollmentDetails.getApiProvDomId();
82         } catch (Exception e) {
83             logger.warn("Error in creating AMF", e);
84         }
85         return responseApiEnrollmentDetails;
86     }
87
88     void deleteAMF() {
89         deleteProviderFunc(amfRegistrationId);
90     }
91
92
93     @Override
94     public boolean deployRapp(Rapp rapp) {
95         logger.debug("Deploying SME functions for Rapp {}", rapp.getName());
96         try {
97             boolean deployState = createProviderDomain(rapp) && createPublishApi(rapp) && createInvoker(rapp);
98             if (deployState) {
99                 rappStateMachine.sendRappEvent(rapp, RappEvent.SMEDEPLOYED);
100             } else {
101                 rappStateMachine.sendRappEvent(rapp, 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 undeployRapp(Rapp rapp) {
112         logger.debug("Undeploying SME functions for Rapp {}", rapp.getName());
113         try {
114             rapp.getSmeInvokers().forEach(this::deleteInvoker);
115             rapp.getSmeServiceApis().forEach(s -> deletePublishApi(s, rapp.getSmeApfId()));
116             rapp.getSmeProviderFunctions().values().forEach(this::deleteProviderFunc);
117             rappStateMachine.sendRappEvent(rapp, RappEvent.SMEUNDEPLOYED);
118             return true;
119         } catch (Exception e) {
120             logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName());
121         }
122         return false;
123     }
124
125     boolean createProviderDomain(Rapp rapp) throws JsonProcessingException {
126         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
127         try {
128             String providerDomainPayload = rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp);
129             if (providerDomainPayload != null) {
130                 APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
131                         objectMapper.readValue(providerDomainPayload, APIProviderEnrolmentDetails.class);
132                 APIProviderEnrolmentDetails responseApiEnrollmentDetails =
133                         providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
134                 if (responseApiEnrollmentDetails.getApiProvFuncs() != null) {
135                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
136                             ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rapp.setSmeApfId(
137                             apiProviderFunctionDetails.getApiProvFuncId()));
138                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
139                             ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rapp.setSmeAefId(
140                             apiProviderFunctionDetails.getApiProvFuncId()));
141                     rapp.setSmeProviderFunctions(responseApiEnrollmentDetails.getApiProvFuncs().stream().collect(
142                             Collectors.toMap(APIProviderFunctionDetails::getApiProvFuncInfo,
143                                     APIProviderFunctionDetails::getApiProvFuncId)));
144                     rappCacheService.putRapp(rapp);
145                     return true;
146                 }
147             }
148         } catch (Exception e) {
149             logger.warn("Error in creating provider domain", e);
150         }
151         return false;
152     }
153
154     Optional<APIProviderFunctionDetails> getProviderFuncId(List<APIProviderFunctionDetails> apiProviderFunctionDetails,
155             ApiProviderFuncRole apiProviderFuncRole) {
156         return apiProviderFunctionDetails.stream()
157                        .filter(apiProviderFunctionDetail -> apiProviderFunctionDetail.getApiProvFuncRole()
158                                                                     .equals(apiProviderFuncRole)).findFirst();
159     }
160
161     void deleteProviderFunc(String registrationId) {
162         providerDefaultApiClient.deleteRegistrationsRegistrationId(registrationId);
163     }
164
165
166     boolean createPublishApi(Rapp rapp) throws JsonProcessingException {
167         logger.debug("Creating publish api for Rapp {}", rapp.getName());
168         try {
169             String providerApiPayload = rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp);
170             if (providerApiPayload != null) {
171                 ServiceAPIDescription serviceAPIDescription =
172                         objectMapper.readValue(providerApiPayload, ServiceAPIDescription.class);
173                 serviceAPIDescription.getAefProfiles().forEach(aefProfile -> {
174                     aefProfile.setAefId(rapp.getSmeProviderFunctions().get(aefProfile.getAefId()));
175                 });
176                 ServiceAPIDescription serviceAPIDescriptionResponse =
177                         publishServiceDefaultApiClient.postApfIdServiceApis(rapp.getSmeApfId(), serviceAPIDescription);
178
179                 if (serviceAPIDescriptionResponse.getAefProfiles() != null) {
180                     rapp.setSmeServiceApis(
181                             serviceAPIDescriptionResponse.getAefProfiles().stream().map(AefProfile::getAefId)
182                                     .collect(Collectors.toList()));
183                     rappCacheService.putRapp(rapp);
184                     return true;
185                 }
186             }
187         } catch (Exception e) {
188             logger.warn("Error in creating publish api", e);
189         }
190         return false;
191     }
192
193     void deletePublishApi(String serviceApiId, String apfId) {
194         publishServiceDefaultApiClient.deleteApfIdServiceApisServiceApiId(serviceApiId, apfId);
195     }
196
197     boolean createInvoker(Rapp rapp) throws JsonProcessingException {
198         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
199         try {
200             String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp);
201             if (invokerPayload != null) {
202                 List<APIInvokerEnrolmentDetails> apiInvokerEnrolmentDetails =
203                         objectMapper.readValue(invokerPayload, new TypeReference<>() { });
204                 apiInvokerEnrolmentDetails.forEach(apiInvokerEnrolmentDetail -> {
205                     APIInvokerEnrolmentDetails apiInvokerEnrolmentDetailsResponse =
206                             invokerDefaultApiClient.postOnboardedInvokers(apiInvokerEnrolmentDetail);
207                     if (apiInvokerEnrolmentDetailsResponse.getApiList() != null) {
208                         rapp.getSmeInvokers().addAll(apiInvokerEnrolmentDetailsResponse.getApiList().stream()
209                                                              .map(com.oransc.rappmanager.sme.invoker.data.ServiceAPIDescription::getApiId)
210                                                              .toList());
211                         rappCacheService.putRapp(rapp);
212                     }
213                 });
214                 return true;
215             }
216         } catch (Exception e) {
217             logger.warn("Error in creating invoker", e);
218         }
219         return false;
220     }
221
222     void deleteInvoker(String invokerId) {
223         invokerDefaultApiClient.deleteOnboardedInvokersOnboardingId(invokerId);
224     }
225 }