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