721c6e9921cd86ab2b2b8ef899738b46cc13aa12
[smo/teiv.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
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  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20 package org.oran.smo.teiv.adapters.focom_to_teiv_adapter.service;
21
22 import com.fasterxml.jackson.core.type.TypeReference;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.fasterxml.jackson.databind.SerializationFeature;
25 import io.fabric8.kubernetes.client.KubernetesClientException;
26 import lombok.extern.slf4j.Slf4j;
27 import org.nephio.focom.v1alpha1.FocomProvisioningRequest;
28 import org.oran.provisioning.o2ims.v1alpha1.ProvisioningRequest;
29 import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.EntityAndRelationshipModel;
30 import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.EntityItem;
31 import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.RelationshipItem;
32
33 import org.springframework.stereotype.Component;
34
35 import java.io.IOException;
36 import java.util.Collections;
37 import java.util.Map;
38 import java.util.List;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41
42
43 import static org.oran.smo.teiv.adapters.common.utils.Constants.ENTITY_OCLOUD_NAMESPACE;
44 import static org.oran.smo.teiv.adapters.common.utils.Constants.SMO_TEIV_CLOUD_PREFIX;
45 import static org.oran.smo.teiv.adapters.common.utils.Constants.ENTITY_NODE_CLUSTER;
46 import static org.oran.smo.teiv.adapters.common.utils.Constants.REL_DEPLOYED_ON;
47 import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildEntityTypeName;
48 import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildTeivFocomRelationshipTypeName;
49
50 @Slf4j
51 @Component
52 public class FocomToTeivModelBuilder {
53
54     private final FocomProvisioningRequestService service;
55     private final EntityAndRelationshipModelService modelService;
56
57     public FocomToTeivModelBuilder(FocomProvisioningRequestService service,
58                                    EntityAndRelationshipModelService modelService) {
59         this.service = service;
60         this.modelService = modelService;
61     }
62
63     public Map<String, Object> getFocomtoTeivJson() throws IOException {
64
65         List<EntityItem> oCloudNamespaces = new ArrayList<>();
66         List<EntityItem> nodeClusters = new ArrayList<>();
67         List<RelationshipItem> deployOnRelationships = new ArrayList<>();
68         List<FocomProvisioningRequest> focomRequests;
69
70         int index = 1;
71
72         try {
73             focomRequests = service.getAllFocomProvisioningRequests();
74         } catch (KubernetesClientException e) {
75             log.error("Failed to retrieve FOCOM provisioning requests from Kubernetes: {}", e.getMessage(), e);
76             return Collections.emptyMap();
77         } catch (Exception e) {
78             log.error("Unexpected error while retrieving FOCOM provisioning requests", e);
79             return Collections.emptyMap();
80         }
81
82         if (focomRequests == null || focomRequests.isEmpty()) {
83             return Collections.emptyMap();
84         }
85
86         for (FocomProvisioningRequest focomProvisioningRequest : focomRequests) {
87
88             validateProvisioningRequest(focomProvisioningRequest);
89
90             EntityItem oCloudNamespace = buildOCloudNamespace(focomProvisioningRequest, index);
91             oCloudNamespaces.add(oCloudNamespace);
92
93             EntityItem nodeCluster = buildNodeCluster(focomProvisioningRequest, index);
94             if (nodeCluster == null || nodeCluster.isEmpty()) {
95                 log.error("Failed to build Nodecluster, attributes missing");
96                 index++;
97                 continue;
98             }
99             nodeClusters.add(nodeCluster);
100
101             RelationshipItem rel = modelService.getTeivRelationshipDeployOn(oCloudNamespace, nodeCluster, index);
102             deployOnRelationships.add(rel);
103
104             index++;
105         }
106
107         Map<String, List<EntityItem>> entities = new HashMap<>();
108         entities.put(
109                 buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_OCLOUD_NAMESPACE),
110                 oCloudNamespaces
111         );
112
113         if (!nodeClusters.isEmpty()) {
114             entities.put(
115                     buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_NODE_CLUSTER),
116                     nodeClusters
117             );
118         }
119
120         Map<String, List<RelationshipItem>> relationships = new HashMap<>();
121         if (!deployOnRelationships.isEmpty()) {
122             relationships.put(
123                     buildTeivFocomRelationshipTypeName(
124                             REL_DEPLOYED_ON,
125                             ENTITY_OCLOUD_NAMESPACE.toUpperCase(),
126                             ENTITY_NODE_CLUSTER.toUpperCase()
127                     ),
128                     deployOnRelationships
129             );
130         }
131
132         EntityAndRelationshipModel entityAndRelationshipModel = new EntityAndRelationshipModel();
133         entityAndRelationshipModel.setEntities(List.of(entities));
134         entityAndRelationshipModel.setRelationships(List.of(relationships));
135
136         ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
137         Map<String, Object> json = mapper.convertValue(entityAndRelationshipModel, new TypeReference<Map<String, Object>>() {
138         });
139
140         log.info(mapper.writeValueAsString(entityAndRelationshipModel));
141         return json;
142     }
143
144     private void validateProvisioningRequest(FocomProvisioningRequest focomProvisioningRequest) {
145         if (!"Fulfilled".equals(focomProvisioningRequest.getStatus().getPhase())) {
146             throw new RuntimeException("Requested Focomprovisioning request is not in Fulfilled phase");
147         }
148     }
149
150     private EntityItem buildOCloudNamespace(FocomProvisioningRequest focomProvisioningRequest, int index) {
151         String namespace = focomProvisioningRequest.getSpec().getOCloudNamespace();
152         return modelService.getOCloudNamespaceEntity(namespace, index);
153     }
154
155     private EntityItem buildNodeCluster(FocomProvisioningRequest focomProvisioningRequest, int index) {
156         ProvisioningRequest o2imsRequest;
157         try {
158             o2imsRequest = service.getO2imsProvisioningRequest(focomProvisioningRequest.getMetadata().getName());
159         } catch (KubernetesClientException e) {
160             log.error("Failed to retrieve O2ims provisioning requests from Kubernetes: {}", e.getMessage(), e);
161             return new EntityItem();
162         } catch (Exception e) {
163             log.error("Unexpected error while retrieving O2ims provisioning requests", e);
164             return new EntityItem();
165         }
166
167         String clusterName = focomProvisioningRequest.getSpec().getTemplateParameters()
168                 .getAdditionalProperties()
169                 .get("clusterName")
170                 .toString();
171
172         String nodeClusterId = String.valueOf(o2imsRequest.getStatus()
173                 .getProvisionedResourceSet()
174                 .getOCloudNodeClusterId());
175
176         return modelService.getNodeClusterEntity(clusterName, nodeClusterId, index);
177     }
178 }
179