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 java.util.function.BiFunction;
38 import lombok.RequiredArgsConstructor;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.http.ResponseEntity;
42 import org.springframework.stereotype.Service;
45 @RequiredArgsConstructor
46 public class DmeDeployer implements RappDeployer {
48 Logger logger = LoggerFactory.getLogger(DmeDeployer.class);
50 private final DataProducerRegistrationApiClient dataProducerRegistrationApiClient;
52 private final DataConsumerApiClient dataConsumerApiClient;
54 private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
56 private final ObjectMapper objectMapper;
58 private final RappInstanceStateMachine rappInstanceStateMachine;
61 public boolean deployRappInstance(Rapp rapp, RappInstance rappInstance) {
62 logger.debug("Deploying DME functions for RappInstance {}", rappInstance.getRappInstanceId());
63 boolean deployState = true;
64 if (rappInstance.getDme().getInfoTypesProducer() != null) {
65 deployState = createProducerInfoTypes(rapp, rappInstance.getDme().getInfoTypesProducer());
67 if (rappInstance.getDme().getInfoTypeConsumer() != null) {
69 deployState && createConsumerInfoTypes(rapp, Set.of(rappInstance.getDme().getInfoTypeConsumer()));
71 if (rappInstance.getDme().getInfoProducer() != null) {
72 deployState = deployState && createInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
74 if (rappInstance.getDme().getInfoConsumer() != null) {
75 deployState = deployState && createInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
78 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYED);
80 rappInstance.setReason("Unable to deploy DME");
81 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYFAILED);
87 public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
88 logger.debug("Undeploying DME functions for RappInstance {}", rappInstance.getRappInstanceId());
89 boolean undeployState = true;
90 if (rappInstance.getDme().getInfoConsumer() != null) {
91 undeployState = deleteInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
93 if (rappInstance.getDme().getInfoProducer() != null) {
94 undeployState = undeployState && deleteInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
97 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED);
99 rappInstance.setReason("Unable to undeploy DME");
100 rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYFAILED);
102 return undeployState;
106 public boolean primeRapp(Rapp rapp) {
107 logger.debug("Priming DME functions for rApp {}", rapp.getRappId());
109 Set<String> requiredInfoTypes = new HashSet<>();
110 for (String producerResourceName : rapp.getRappResources().getDme().getInfoProducers()) {
111 String producerPayload =
112 rappCsarConfigurationHandler.getDmeInfoProducerPayload(rapp, producerResourceName);
113 ProducerRegistrationInfo producerRegistrationInfo =
114 objectMapper.readValue(producerPayload, ProducerRegistrationInfo.class);
115 requiredInfoTypes.addAll(producerRegistrationInfo.getSupportedInfoTypes());
117 for (String consumerResourceName : rapp.getRappResources().getDme().getInfoConsumers()) {
118 String consumerPayload =
119 rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rapp, consumerResourceName);
120 ConsumerJob consumerJob = objectMapper.readValue(consumerPayload, ConsumerJob.class);
121 requiredInfoTypes.add(consumerJob.getInfoTypeId());
123 Set<String> allInfoTypes = new HashSet<>(rapp.getRappResources().getDme().getProducerInfoTypes());
124 allInfoTypes.addAll(rapp.getRappResources().getDme().getConsumerInfoTypes());
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 createProducerInfoTypes(Rapp rApp, Set<String> infoTypes) {
149 logger.debug("Creating DME producer info types {} for rApp {}", infoTypes, rApp.getRappId());
150 return createInfoTypes(rApp, infoTypes, rappCsarConfigurationHandler::getDmeProducerInfoTypePayload);
153 boolean createConsumerInfoTypes(Rapp rApp, Set<String> infoTypes) {
154 logger.debug("Creating DME consumer info types {} for rApp {}", infoTypes, rApp.getRappId());
155 return createInfoTypes(rApp, infoTypes, rappCsarConfigurationHandler::getDmeConsumerInfoTypePayload);
158 boolean createInfoTypes(Rapp rApp, Set<String> infoTypes, BiFunction<Rapp, String, String> payloadReader) {
160 Map<String, ProducerInfoTypeInfo> producerInfoTypeInfoMap = new HashMap<>();
161 for (String infoType : infoTypes) {
162 String infoTypePayload = payloadReader.apply(rApp, infoType);
163 if (infoTypePayload != null && !infoTypePayload.isEmpty()) {
164 producerInfoTypeInfoMap.put(infoType,
165 objectMapper.readValue(infoTypePayload, ProducerInfoTypeInfo.class));
168 return producerInfoTypeInfoMap.entrySet().stream().map(stringProducerInfoTypeInfoEntry -> {
169 ResponseEntity<Object> objectResponseEntity = dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(
170 stringProducerInfoTypeInfoEntry.getKey(), stringProducerInfoTypeInfoEntry.getValue());
171 return objectResponseEntity.getStatusCode().is2xxSuccessful();
172 }).reduce(true, (a, b) -> a && b);
173 } catch (Exception e) {
174 logger.warn("Error in creating info types {} for rApp {}", infoTypes, rApp.getRappId(), e);
179 boolean createInfoProducer(Rapp rApp, String producerResource) {
180 logger.debug("Creating DME info producer {} for rApp {}", producerResource, rApp.getRappId());
182 String infoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rApp, producerResource);
183 ProducerRegistrationInfo producerRegistrationInfo =
184 objectMapper.readValue(infoProducerPayload, ProducerRegistrationInfo.class);
186 ResponseEntity<Object> objectResponseEntity =
187 dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(producerResource,
188 producerRegistrationInfo);
189 return objectResponseEntity.getStatusCode().is2xxSuccessful();
190 } catch (Exception e) {
191 logger.warn("Error in creating info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
196 boolean createInfoConsumer(Rapp rApp, String consumerResource) {
197 logger.debug("Creating DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
199 String infoJobPayload = rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rApp, consumerResource);
200 ConsumerJob consumerJob = objectMapper.readValue(infoJobPayload, ConsumerJob.class);
201 ResponseEntity<Object> objectResponseEntity =
202 dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(consumerResource, consumerJob);
203 return objectResponseEntity.getStatusCode().is2xxSuccessful();
204 } catch (Exception e) {
205 logger.warn("Error in creating info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);
210 boolean deleteInfoProducer(Rapp rApp, String producerResource) {
211 logger.debug("Deleting DME info producer {} for rApp {}", producerResource, rApp.getRappId());
213 ResponseEntity<Object> objectResponseEntity =
214 dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(producerResource);
215 return objectResponseEntity.getStatusCode().is2xxSuccessful();
216 } catch (Exception e) {
217 logger.warn("Error in deleting info producer {} for rApp {}", producerResource, rApp.getRappId(), e);
222 boolean deleteInfoConsumer(Rapp rApp, String consumerResource) {
223 logger.debug("Deleting DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
225 ResponseEntity<Object> objectResponseEntity =
226 dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(consumerResource);
227 return objectResponseEntity.getStatusCode().is2xxSuccessful();
228 } catch (Exception e) {
229 logger.warn("Error in deleting info consumer {} for rApp {}", consumerResource, rApp.getRappId(), e);