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 rappInstance.setReason("Unable to deploy DME");
84 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYFAILED);
90 public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
91 logger.debug("Undeploying DME functions for RappInstance {}", rappInstance.getRappInstanceId());
92 boolean undeployState = true;
93 if (rappInstance.getDme().getInfoConsumer() != null) {
94 undeployState = deleteInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
96 if (rappInstance.getDme().getInfoProducer() != null) {
97 undeployState = undeployState && deleteInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
100 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED);
102 rappInstance.setReason("Unable to undeploy DME");
103 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYFAILED);
105 return undeployState;
109 public boolean primeRapp(Rapp rapp) {
110 logger.debug("Priming DME functions for rApp {}", rapp.getRappId());
112 Set<String> requiredInfoTypes = new HashSet<>();
113 for (String producerResourceName : rapp.getRappResources().getDme().getInfoProducers()) {
114 String producerPayload =
115 rappCsarConfigurationHandler.getDmeInfoProducerPayload(rapp, producerResourceName);
116 ProducerRegistrationInfo producerRegistrationInfo =
117 objectMapper.readValue(producerPayload, ProducerRegistrationInfo.class);
118 requiredInfoTypes.addAll(producerRegistrationInfo.getSupportedInfoTypes());
120 for (String consumerResourceName : rapp.getRappResources().getDme().getInfoConsumers()) {
121 String consumerPayload =
122 rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rapp, consumerResourceName);
123 ConsumerJob consumerJob = objectMapper.readValue(consumerPayload, ConsumerJob.class);
124 requiredInfoTypes.add(consumerJob.getInfoTypeId());
126 Set<String> allInfoTypes = new HashSet<>(rapp.getRappResources().getDme().getInfoTypes());
127 requiredInfoTypes.removeAll(allInfoTypes);
128 if (!requiredInfoTypes.isEmpty()) {
129 allInfoTypes.addAll(dataProducerRegistrationApiClient.getInfoTypdentifiers());
130 requiredInfoTypes.removeAll(allInfoTypes);
131 if (!requiredInfoTypes.isEmpty()) {
132 rapp.setReason(String.format("Invalid rapp package as the following info types cannot be found %s",
137 } catch (Exception e) {
138 logger.warn("Failed to prime DME", e);
139 rapp.setReason("Failed to prime DME");
145 public boolean deprimeRapp(Rapp rapp) {
146 logger.debug("Depriming DME functions for rApp {}", rapp.getRappId());
150 boolean createInfoTypes(Rapp rApp, Set<String> infoTypes) {
151 logger.debug("Creating DME info types {} for rApp {}", infoTypes, rApp.getRappId());
153 Map<String, ProducerInfoTypeInfo> producerInfoTypeInfoMap = new HashMap<>();
154 for (String infoType : infoTypes) {
155 String infoTypePayload = rappCsarConfigurationHandler.getDmeInfoTypePayload(rApp, infoType);
156 if (infoTypePayload != null && !infoTypePayload.isEmpty()) {
157 producerInfoTypeInfoMap.put(infoType,
158 objectMapper.readValue(infoTypePayload, ProducerInfoTypeInfo.class));
161 return producerInfoTypeInfoMap.entrySet().stream().map(stringProducerInfoTypeInfoEntry -> {
162 ResponseEntity<Object> objectResponseEntity = dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(
163 stringProducerInfoTypeInfoEntry.getKey(), stringProducerInfoTypeInfoEntry.getValue());
164 return objectResponseEntity.getStatusCode().is2xxSuccessful();
165 }).reduce(true, (a, b) -> a && b);
166 } catch (Exception e) {
167 logger.warn("Error in creating info types {} for rApp {}", infoTypes, rApp.getRappId(), e);
172 boolean createInfoProducer(Rapp rApp, String producerResource) {
173 logger.debug("Creating DME info producer {} for rApp {}", producerResource, rApp.getRappId());
175 String infoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rApp, producerResource);
176 ProducerRegistrationInfo producerRegistrationInfo =
177 objectMapper.readValue(infoProducerPayload, ProducerRegistrationInfo.class);
179 ResponseEntity<Object> objectResponseEntity =
180 dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(producerResource,
181 producerRegistrationInfo);
182 return objectResponseEntity.getStatusCode().is2xxSuccessful();
183 } catch (Exception e) {
184 logger.warn("Error in creating info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
189 boolean createInfoConsumer(Rapp rApp, String consumerResource) {
190 logger.debug("Creating DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
192 String infoJobPayload = rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rApp, consumerResource);
193 ConsumerJob consumerJob = objectMapper.readValue(infoJobPayload, ConsumerJob.class);
194 ResponseEntity<Object> objectResponseEntity =
195 dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(consumerResource, consumerJob);
196 return objectResponseEntity.getStatusCode().is2xxSuccessful();
197 } catch (Exception e) {
198 logger.warn("Error in creating info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);
203 boolean deleteInfoProducer(Rapp rApp, String producerResource) {
204 logger.debug("Deleting DME info producer {} for rApp {}", producerResource, rApp.getRappId());
206 ResponseEntity<Object> objectResponseEntity =
207 dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(producerResource);
208 return objectResponseEntity.getStatusCode().is2xxSuccessful();
209 } catch (Exception e) {
210 logger.warn("Error in deleting info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
215 boolean deleteInfoConsumer(Rapp rApp, String consumerResource) {
216 logger.debug("Deleting DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
218 ResponseEntity<Object> objectResponseEntity =
219 dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(consumerResource);
220 return objectResponseEntity.getStatusCode().is2xxSuccessful();
221 } catch (Exception e) {
222 logger.warn("Error in deleting info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);