d82ef47c1415af5fd8daefb7c4d0ee6cb4a543f9
[nonrtric/plt/rappmanager.git] / rapp-manager-dme / src / main / java / com / oransc / rappmanager / dme / service / DmeDeployer.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.dme.service;
20
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;
35 import java.util.Map;
36 import java.util.Set;
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;
42
43 @Service
44 @RequiredArgsConstructor
45 public class DmeDeployer implements RappDeployer {
46
47     Logger logger = LoggerFactory.getLogger(DmeDeployer.class);
48
49     private final DataProducerRegistrationApiClient dataProducerRegistrationApiClient;
50
51     private final DataConsumerApiClient dataConsumerApiClient;
52
53     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
54
55     private final ObjectMapper objectMapper;
56
57     private final RappInstanceStateMachine rappInstanceStateMachine;
58
59     @Override
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());
68             }
69             if (rappInstance.getDme().getInfoTypeConsumer() != null) {
70                 infoTypes.add(rappInstance.getDme().getInfoTypeConsumer());
71             }
72             deployState = createInfoTypes(rapp, infoTypes);
73         }
74         if (rappInstance.getDme().getInfoProducer() != null) {
75             deployState = deployState && createInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
76         }
77         if (rappInstance.getDme().getInfoConsumer() != null) {
78             deployState = deployState && createInfoConsumer(rapp, rappInstance.getDme().getInfoConsumer());
79         }
80         if (deployState) {
81             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYED);
82         } else {
83             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYFAILED);
84         }
85         return deployState;
86     }
87
88     @Override
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());
94         }
95         if (rappInstance.getDme().getInfoProducer() != null) {
96             undeployState = undeployState && deleteInfoProducer(rapp, rappInstance.getDme().getInfoProducer());
97         }
98         if (undeployState) {
99             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED);
100         } else {
101             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYFAILED);
102         }
103         return undeployState;
104     }
105
106     @Override
107     public boolean primeRapp(Rapp rapp) {
108         logger.debug("Priming DME functions for rApp {}", rapp.getRappId());
109         try {
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());
117             }
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());
123             }
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",
131                                     requiredInfoTypes));
132                 }
133             }
134             return true;
135         } catch (Exception e) {
136             logger.warn("Failed to prime DME", e);
137             rapp.setReason("Failed to prime DME");
138             return false;
139         }
140     }
141
142     @Override
143     public boolean deprimeRapp(Rapp rapp) {
144         logger.debug("Depriming DME functions for rApp {}", rapp.getRappId());
145         return true;
146     }
147
148     boolean createInfoTypes(Rapp rApp, Set<String> infoTypes) {
149         logger.debug("Creating DME info types {} for rApp {}", infoTypes, rApp.getRappId());
150         try {
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));
157                 }
158             }
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);
166             return false;
167         }
168     }
169
170     boolean createInfoProducer(Rapp rApp, String producerResource) {
171         logger.debug("Creating DME info producer {} for rApp {}", producerResource, rApp.getRappId());
172         try {
173             String infoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rApp, producerResource);
174             ProducerRegistrationInfo producerRegistrationInfo =
175                     objectMapper.readValue(infoProducerPayload, ProducerRegistrationInfo.class);
176
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);
183             return false;
184         }
185     }
186
187     boolean createInfoConsumer(Rapp rApp, String consumerResource) {
188         logger.debug("Creating DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
189         try {
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);
197             return false;
198         }
199     }
200
201     boolean deleteInfoProducer(Rapp rApp, String producerResource) {
202         logger.debug("Deleting DME info producer {} for rApp {}", producerResource, rApp.getRappId());
203         try {
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);
209             return false;
210         }
211     }
212
213     boolean deleteInfoConsumer(Rapp rApp, String consumerResource) {
214         logger.debug("Deleting DME info consumer {} for rApp {}", consumerResource, rApp.getRappId());
215         try {
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);
221             return false;
222         }
223     }
224 }