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 rapp.setReason(String.format("Invalid rapp package as the following info types cannot be found %s",
135 } catch (Exception e) {
136 logger.warn("Failed to prime DME", e);
137 rapp.setReason("Failed to prime DME");
143 public boolean deprimeRapp(Rapp rapp) {
144 logger.debug("Depriming DME functions for rApp {}", rapp.getRappId());
148 boolean createInfoTypes(Rapp rApp, Set<String> infoTypes) {
149 logger.debug("Creating DME info types {} for rApp {}", infoTypes, rApp.getRappId());
151 Map<String, ProducerInfoTypeInfo> producerInfoTypeInfoMap = new HashMap<>();
152 for (String infoType : infoTypes) {
153 String infoTypePayload = rappCsarConfigurationHandler.getDmeInfoTypePayload(rApp, infoType);
154 if (infoTypePayload != null && !infoTypePayload.isEmpty()) {
155 producerInfoTypeInfoMap.put(infoType,
156 objectMapper.readValue(infoTypePayload, ProducerInfoTypeInfo.class));
159 return producerInfoTypeInfoMap.entrySet().stream().map(stringProducerInfoTypeInfoEntry -> {
160 ResponseEntity<Object> objectResponseEntity = dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(
161 stringProducerInfoTypeInfoEntry.getKey(), stringProducerInfoTypeInfoEntry.getValue());
162 return objectResponseEntity.getStatusCode().is2xxSuccessful();
163 }).reduce(true, (a, b) -> a && b);
164 } catch (Exception e) {
165 logger.warn("Error in creating info types {} for rApp {}", infoTypes, rApp.getRappId(), e);
170 boolean createInfoProducer(Rapp rApp, String producerResource) {
171 logger.debug("Creating DME info producer {} for rApp {}", producerResource, rApp.getRappId());
173 String infoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rApp, producerResource);
174 ProducerRegistrationInfo producerRegistrationInfo =
175 objectMapper.readValue(infoProducerPayload, ProducerRegistrationInfo.class);
177 ResponseEntity<Object> objectResponseEntity =
178 dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(producerResource,
179 producerRegistrationInfo);
180 return objectResponseEntity.getStatusCode().is2xxSuccessful();
181 } catch (Exception e) {
182 logger.warn("Error in creating info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
187 boolean createInfoConsumer(Rapp rApp, String consumerResource) {
188 logger.debug("Creating DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
190 String infoJobPayload = rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rApp, consumerResource);
191 ConsumerJob consumerJob = objectMapper.readValue(infoJobPayload, ConsumerJob.class);
192 ResponseEntity<Object> objectResponseEntity =
193 dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(consumerResource, consumerJob);
194 return objectResponseEntity.getStatusCode().is2xxSuccessful();
195 } catch (Exception e) {
196 logger.warn("Error in creating info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);
201 boolean deleteInfoProducer(Rapp rApp, String producerResource) {
202 logger.debug("Deleting DME info producer {} for rApp {}", producerResource, rApp.getRappId());
204 ResponseEntity<Object> objectResponseEntity =
205 dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(producerResource);
206 return objectResponseEntity.getStatusCode().is2xxSuccessful();
207 } catch (Exception e) {
208 logger.warn("Error in deleting info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
213 boolean deleteInfoConsumer(Rapp rApp, String consumerResource) {
214 logger.debug("Deleting DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
216 ResponseEntity<Object> objectResponseEntity =
217 dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(consumerResource);
218 return objectResponseEntity.getStatusCode().is2xxSuccessful();
219 } catch (Exception e) {
220 logger.warn("Error in deleting info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);