Added oparent to sdc main
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / migration / tasks / mig1806 / SDCInstancesMigration.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.asdctool.migration.tasks.mig1806;
22
23 import fj.data.Either;
24 import org.openecomp.sdc.asdctool.migration.core.DBVersion;
25 import org.openecomp.sdc.asdctool.migration.core.task.Migration;
26 import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
27 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
28 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
29 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
30 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
31 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
32 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
33 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
39 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
41 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
42 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
43 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
44 import org.openecomp.sdc.common.log.wrappers.Logger;
45 import org.springframework.stereotype.Component;
46
47 import java.math.BigInteger;
48 import java.util.*;
49 import java.util.Map.Entry;
50
51 @Component
52 public class SDCInstancesMigration implements Migration {
53
54     private JanusGraphDao janusGraphDao;
55     private NodeTemplateOperation nodeTemplateOperation;
56
57     private static final Logger log = Logger.getLogger(SDCInstancesMigration.class);
58
59     private static final String ALLOTTED_CATEGORY = "Allotted Resource";
60     
61     private static final List<String> UUID_PROPS_NAMES = Arrays.asList("providing_service_uuid", "providing_service_uuid");
62  
63  
64     public SDCInstancesMigration(JanusGraphDao janusGraphDao, NodeTemplateOperation nodeTemplateOperation) {
65         this.janusGraphDao = janusGraphDao;
66         this.nodeTemplateOperation = nodeTemplateOperation;
67     }
68
69     @Override
70     public String description() {
71         return "connect instances in container to its origins";
72     }
73
74     @Override
75     public DBVersion getVersion() {
76         return DBVersion.from(BigInteger.valueOf(1806), BigInteger.valueOf(0));
77     }
78
79     @Override
80     public MigrationResult migrate() {
81         StorageOperationStatus status = connectAllContainers();
82
83         return status == StorageOperationStatus.OK ? MigrationResult.success() : MigrationResult.error("failed to create connection between instances and origins. Error : " + status);
84     }
85
86     private StorageOperationStatus connectAllContainers() {
87         StorageOperationStatus status;
88         Map<GraphPropertyEnum, Object> hasNotProps = new EnumMap<>(GraphPropertyEnum.class);
89         hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
90         hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC);
91
92         status = janusGraphDao
93             .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, null, hasNotProps, JsonParseFlagEnum.ParseAll)
94                 .either(this::connectAll, this::handleError);
95         return status;
96     }
97
98     private StorageOperationStatus handleError(JanusGraphOperationStatus err) {
99         return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
100             JanusGraphOperationStatus.NOT_FOUND == err ? JanusGraphOperationStatus.OK : err);
101     }
102
103     private StorageOperationStatus connectAll(List<GraphVertex> containersV) {
104         StorageOperationStatus status = StorageOperationStatus.OK;
105         for (GraphVertex container : containersV) {
106             status = handleOneContainer(container);
107             if (status != StorageOperationStatus.OK) {
108                 break;
109             }
110         }
111         return status;
112     }
113
114     private StorageOperationStatus handleOneContainer(GraphVertex containerV) {
115         StorageOperationStatus status = StorageOperationStatus.OK;
116
117         boolean needConnectAllotted = false;
118         ComponentTypeEnum componentType = containerV.getType();
119         Map<String, MapPropertiesDataDefinition> instanceProperties = null;
120         if (componentType == ComponentTypeEnum.RESOURCE) {
121             Either<GraphVertex, JanusGraphOperationStatus> subcategoryV = janusGraphDao
122                 .getChildVertex(containerV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
123             if (subcategoryV.isRight()) {
124                 log.debug("Failed to fetch category vertex for resource {} error {}  ", containerV.getUniqueId(), subcategoryV.right().value());
125                 return StorageOperationStatus.GENERAL_ERROR;
126             }
127             GraphVertex catV = subcategoryV.left().value();
128             Map<GraphPropertyEnum, Object> metadataProperties = catV.getMetadataProperties();
129
130             String name = (String) metadataProperties.get(GraphPropertyEnum.NAME);
131             if (name.equals(ALLOTTED_CATEGORY)) {
132                 log.debug("Find allotted  resource {}.", containerV.getUniqueId());
133                 needConnectAllotted = true;
134                 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> instProperties = getInstProperties(containerV);
135                 if ( instProperties.isRight() ){
136                     return instProperties.right().value();
137                 }
138                 instanceProperties = instProperties.left().value();
139             }
140         }
141         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
142         if (jsonComposition != null && !jsonComposition.isEmpty()) {
143             try {
144                 status = connectInstances(containerV, needConnectAllotted, instanceProperties, jsonComposition);
145
146             } finally {
147                 if (status == StorageOperationStatus.OK) {
148                     janusGraphDao.commit();
149                 } else {
150                     janusGraphDao.rollback();
151                 }
152             }
153         }
154         return status;
155     }
156
157     private Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> getInstProperties(GraphVertex containerV) {
158         Map<String, MapPropertiesDataDefinition> instanceProperties;
159        Either<GraphVertex, JanusGraphOperationStatus> instProps = janusGraphDao
160            .getChildVertex(containerV, EdgeLabelEnum.INST_PROPERTIES, JsonParseFlagEnum.ParseAll);
161       
162         if (instProps.isRight()) {
163             if (instProps.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
164                 instanceProperties = new HashMap<>();
165             } else {
166                 log.debug("Failed to fetch instance properties vertex for resource {} error {}  ", containerV.getUniqueId(), instProps.right().value());
167                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
168             }
169         } else {
170             instanceProperties = (Map<String, MapPropertiesDataDefinition>) instProps.left().value().getJson();
171         }
172         return Either.left(instanceProperties);
173     }
174
175     private StorageOperationStatus connectInstances(GraphVertex containerV, boolean needConnectAllotted, Map<String, MapPropertiesDataDefinition> instanceProperties,
176             Map<String, CompositionDataDefinition> jsonComposition) {
177         StorageOperationStatus status = StorageOperationStatus.OK;
178         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
179         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
180         for (Map.Entry<String, ComponentInstanceDataDefinition> entry : componentInstances.entrySet()) {
181             status = handleInstance(containerV, needConnectAllotted, instanceProperties, entry);
182             if ( status != StorageOperationStatus.OK){
183                 if ( status == StorageOperationStatus.NOT_FOUND ){
184                     log.debug("reset status and continue");
185                     status = StorageOperationStatus.OK;
186                 }else{
187                     log.debug("Failed handle instance. exit");
188                     break;
189                 }
190             }
191         }
192         return status;
193     }
194
195     private StorageOperationStatus handleInstance(GraphVertex containerV, boolean needConnectAllotted, Map<String, MapPropertiesDataDefinition> instanceProperties, Map.Entry<String, ComponentInstanceDataDefinition> entry) {
196         ComponentInstanceDataDefinition instance = entry.getValue();
197         StorageOperationStatus status = nodeTemplateOperation.createInstanceEdge(containerV, instance);
198         if (status != StorageOperationStatus.OK) {
199             if ( status == StorageOperationStatus.NOT_FOUND ){
200                 Boolean highest = (Boolean) containerV.getMetadataProperties().get(GraphPropertyEnum.IS_HIGHEST_VERSION);
201                 log.debug("No origin for instance {} with ID {}. The component is highest ={},  Reset status and continue.. ", instance.getUniqueId(), instance.getComponentUid(), highest);
202                 status = StorageOperationStatus.OK;
203             }else{
204                 log.debug("Failed to connect in container {} instance {} to origin {} error {}  ", containerV.getUniqueId(), instance.getUniqueId(), instance.getComponentUid(), status);
205                 return status;
206             }
207         }
208         if (needConnectAllotted) {
209             status = connectAllotedInstances(containerV, instanceProperties, instance);
210         }
211         return status;
212     }
213
214     private StorageOperationStatus connectAllotedInstances(GraphVertex containerV, Map<String, MapPropertiesDataDefinition> instanceProperties, ComponentInstanceDataDefinition instance) {
215         StorageOperationStatus status = StorageOperationStatus.OK;
216         if ( instanceProperties != null ){
217             MapPropertiesDataDefinition mapPropertiesDataDefinition = instanceProperties.get(instance.getUniqueId());
218             if ( mapPropertiesDataDefinition != null ){
219                 status = checkAllottedPropertyAndConnect(containerV, instance, mapPropertiesDataDefinition);
220             }else{
221                 log.debug("No isntances properties for instance {}", instance.getUniqueId());
222             }
223         }
224         return status;
225     }
226
227     private StorageOperationStatus checkAllottedPropertyAndConnect(GraphVertex containerV, ComponentInstanceDataDefinition instance, MapPropertiesDataDefinition mapPropertiesDataDefinition) {
228         Map<String, PropertyDataDefinition> mapToscaDataDefinition = mapPropertiesDataDefinition.getMapToscaDataDefinition();
229         StorageOperationStatus status = StorageOperationStatus.OK;
230         Optional<Entry<String, PropertyDataDefinition>> findFirst = mapToscaDataDefinition
231                 .entrySet()
232                 .stream()
233                 .filter(e -> UUID_PROPS_NAMES.contains(e.getKey()))
234                 .findFirst();
235         
236         if ( findFirst.isPresent() ){
237             PropertyDataDefinition property = findFirst.get().getValue();
238             String serviceUUID = property.getValue(); 
239             if ( serviceUUID != null ){
240                 log.debug("Defined reference service on property {} value {} on instance {}", property.getName(), property.getValue(), instance.getUniqueId() );
241                 status = nodeTemplateOperation.createAllottedOfEdge(containerV.getUniqueId(), instance.getUniqueId(), serviceUUID);
242                 if ( status != StorageOperationStatus.OK ){
243                     if ( status == StorageOperationStatus.NOT_FOUND ){
244                         Boolean highest = (Boolean) containerV.getMetadataProperties().get(GraphPropertyEnum.IS_HIGHEST_VERSION);
245                         log.debug("No origin for allotted reference {} with UUID {}. the component highest = {}, Reset status and continue.. ", instance.getUniqueId(), serviceUUID, highest);
246                         status = StorageOperationStatus.OK;
247                     }else{
248                         log.debug("Failed to connect in container {} instance {} to allotted service {} error {}  ", containerV.getUniqueId(), instance.getUniqueId(), instance.getComponentUid(), status);
249                         return status;
250                     }
251                 }
252             }else{
253                 log.debug("No value for property {} on instance {}", property.getName(),instance.getUniqueId() );
254             }
255         }else{
256             log.debug("No sercific properties of dependencies for instance {}", instance.getUniqueId());
257         }
258         return status;
259     }
260
261 }