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
9 * http://www.apache.org/licenses/LICENSE-2.0
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========================================================================
19 package com.oransc.rappmanager.dme.service;
21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import com.oransc.rappmanager.dme.data.ConsumerJob;
23 import com.oransc.rappmanager.dme.data.ProducerInfoTypeInfo;
24 import com.oransc.rappmanager.dme.data.ProducerRegistrationInfo;
25 import com.oransc.rappmanager.dme.rest.DataConsumerApiClient;
26 import com.oransc.rappmanager.dme.rest.DataProducerRegistrationApiClient;
27 import com.oransc.rappmanager.models.RappDeployer;
28 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
29 import com.oransc.rappmanager.models.rapp.Rapp;
30 import com.oransc.rappmanager.models.rapp.RappEvent;
31 import com.oransc.rappmanager.models.rappinstance.RappInstance;
32 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
33 import java.util.HashMap;
34 import java.util.HashSet;
37 import lombok.RequiredArgsConstructor;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.http.ResponseEntity;
41 import org.springframework.stereotype.Service;
44 @RequiredArgsConstructor
45 public class DmeDeployer implements RappDeployer {
47 Logger logger = LoggerFactory.getLogger(DmeDeployer.class);
49 private final DataProducerRegistrationApiClient dataProducerRegistrationApiClient;
51 private final DataConsumerApiClient dataConsumerApiClient;
53 private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
55 private final ObjectMapper objectMapper;
57 private final RappInstanceStateMachine rappInstanceStateMachine;
60 public boolean deployRappInstance(Rapp rapp, RappInstance rappInstance) {
61 logger.debug("Deploying DME functions for RappInstance {}", rappInstance.getRappInstanceId());
62 boolean deployState = true;
63 if (rappInstance.getDme().getInfoTypesProducer() != null
64 || rappInstance.getDme().getInfoTypeConsumer() != null) {
65 Set<String> infoTypes = new HashSet<>();
66 if (rappInstance.getDme().getInfoTypesProducer() != null) {
67 infoTypes.addAll(rappInstance.getDme().getInfoTypesProducer());
69 if (rappInstance.getDme().getInfoTypeConsumer() != null) {
70 infoTypes.add(rappInstance.getDme().getInfoTypeConsumer());
72 deployState = createInfoTypes(rapp, infoTypes);
74 if (rappInstance.getDme().getInfoProducer() != null) {
75 deployState = deployState && createInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
77 if (rappInstance.getDme().getInfoConsumer() != null) {
78 deployState = deployState && createInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
81 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYED);
83 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYFAILED);
89 public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
90 logger.debug("Undeploying DME functions for RappInstance {}", rappInstance.getRappInstanceId());
91 boolean undeployState = true;
92 if (rappInstance.getDme().getInfoConsumer() != null) {
93 undeployState = deleteInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
95 if (rappInstance.getDme().getInfoProducer() != null) {
96 undeployState = undeployState && deleteInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
99 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED);
101 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYFAILED);
103 return undeployState;
107 public boolean primeRapp(Rapp rapp) {
108 logger.debug("Priming DME functions for rApp {}", rapp.getRappId());
110 Set<String> requiredInfoTypes = new HashSet<>();
111 for (String producerResourceName : rapp.getRappResources().getDme().getInfoProducers()) {
112 String producerPayload =
113 rappCsarConfigurationHandler.getDmeInfoProducerPayload(rapp, producerResourceName);
114 ProducerRegistrationInfo producerRegistrationInfo =
115 objectMapper.readValue(producerPayload, ProducerRegistrationInfo.class);
116 requiredInfoTypes.addAll(producerRegistrationInfo.getSupportedInfoTypes());
118 for (String consumerResourceName : rapp.getRappResources().getDme().getInfoConsumers()) {
119 String consumerPayload =
120 rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rapp, consumerResourceName);
121 ConsumerJob consumerJob = objectMapper.readValue(consumerPayload, ConsumerJob.class);
122 requiredInfoTypes.add(consumerJob.getInfoTypeId());
124 Set<String> allInfoTypes = new HashSet<>(rapp.getRappResources().getDme().getInfoTypes());
125 requiredInfoTypes.removeAll(allInfoTypes);
126 if (!requiredInfoTypes.isEmpty()) {
127 allInfoTypes.addAll(dataProducerRegistrationApiClient.getInfoTypdentifiers());
128 requiredInfoTypes.removeAll(allInfoTypes);
129 if (!requiredInfoTypes.isEmpty()) {
130 logger.info("Invalid rapp package as the following info types cannot be found {}",
132 rapp.setIsDmeValid(false);
134 rapp.setIsDmeValid(true);
137 rapp.setIsDmeValid(true);
140 } catch (Exception e) {
141 logger.warn("Failed to prime DME", e);
142 rapp.setIsDmeValid(false);
148 public boolean deprimeRapp(Rapp rapp) {
149 logger.debug("Depriming DME functions for rApp {}", rapp.getRappId());
150 rapp.setIsDmeValid(null);
154 boolean createInfoTypes(Rapp rApp, Set<String> infoTypes) {
155 logger.debug("Creating DME info types {} for rApp {}", infoTypes, rApp.getRappId());
157 Map<String, ProducerInfoTypeInfo> producerInfoTypeInfoMap = new HashMap<>();
158 for (String infoType : infoTypes) {
159 String infoTypePayload = rappCsarConfigurationHandler.getDmeInfoTypePayload(rApp, infoType);
160 if (infoTypePayload != null && !infoTypePayload.isEmpty()) {
161 producerInfoTypeInfoMap.put(infoType,
162 objectMapper.readValue(infoTypePayload, ProducerInfoTypeInfo.class));
165 return producerInfoTypeInfoMap.entrySet().stream().map(stringProducerInfoTypeInfoEntry -> {
166 ResponseEntity<Object> objectResponseEntity = dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(
167 stringProducerInfoTypeInfoEntry.getKey(), stringProducerInfoTypeInfoEntry.getValue());
168 return objectResponseEntity.getStatusCode().is2xxSuccessful();
169 }).reduce(true, (a, b) -> a && b);
170 } catch (Exception e) {
171 logger.warn("Error in creating info types {} for rApp {}", infoTypes, rApp.getRappId(), e);
176 boolean createInfoProducer(Rapp rApp, String producerResource) {
177 logger.debug("Creating DME info producer {} for rApp {}", producerResource, rApp.getRappId());
179 String infoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rApp, producerResource);
180 ProducerRegistrationInfo producerRegistrationInfo =
181 objectMapper.readValue(infoProducerPayload, ProducerRegistrationInfo.class);
183 ResponseEntity<Object> objectResponseEntity =
184 dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(producerResource,
185 producerRegistrationInfo);
186 return objectResponseEntity.getStatusCode().is2xxSuccessful();
187 } catch (Exception e) {
188 logger.warn("Error in creating info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
193 boolean createInfoConsumer(Rapp rApp, String consumerResource) {
194 logger.debug("Creating DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
196 String infoJobPayload = rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rApp, consumerResource);
197 ConsumerJob consumerJob = objectMapper.readValue(infoJobPayload, ConsumerJob.class);
198 ResponseEntity<Object> objectResponseEntity =
199 dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(consumerResource, consumerJob);
200 return objectResponseEntity.getStatusCode().is2xxSuccessful();
201 } catch (Exception e) {
202 logger.warn("Error in creating info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);
207 boolean deleteInfoProducer(Rapp rApp, String producerResource) {
208 logger.debug("Deleting DME info producer {} for rApp {}", producerResource, rApp.getRappId());
210 ResponseEntity<Object> objectResponseEntity =
211 dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(producerResource);
212 return objectResponseEntity.getStatusCode().is2xxSuccessful();
213 } catch (Exception e) {
214 logger.warn("Error in deleting info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
219 boolean deleteInfoConsumer(Rapp rApp, String consumerResource) {
220 logger.debug("Deleting DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
222 ResponseEntity<Object> objectResponseEntity =
223 dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(consumerResource);
224 return objectResponseEntity.getStatusCode().is2xxSuccessful();
225 } catch (Exception e) {
226 logger.warn("Error in deleting info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);