Upgrade SDC from Titan to Janus Graph
[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.janusgraph.JanusGraphOperationStatus;
8 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
9 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
10 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
11 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
12 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
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.jsonjanusgraph.enums.JsonConstantKeysEnum;
21 import org.openecomp.sdc.be.model.jsonjanusgraph.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 JanusGraphDao janusGraphDao;
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(JanusGraphDao janusGraphDao, NodeTemplateOperation nodeTemplateOperation) {
45         this.janusGraphDao = janusGraphDao;
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 = janusGraphDao
73             .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, null, hasNotProps, JsonParseFlagEnum.ParseAll)
74                 .either(this::connectAll, this::handleError);
75         return status;
76     }
77
78     private StorageOperationStatus handleError(JanusGraphOperationStatus err) {
79         return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
80             JanusGraphOperationStatus.NOT_FOUND == err ? JanusGraphOperationStatus.OK : err);
81     }
82
83     private StorageOperationStatus connectAll(List<GraphVertex> containersV) {
84         StorageOperationStatus status = StorageOperationStatus.OK;
85         for (GraphVertex container : containersV) {
86             status = handleOneContainer(container);
87             if (status != StorageOperationStatus.OK) {
88                 break;
89             }
90         }
91         return status;
92     }
93
94     private StorageOperationStatus handleOneContainer(GraphVertex containerV) {
95         StorageOperationStatus status = StorageOperationStatus.OK;
96
97         boolean needConnectAllotted = false;
98         ComponentTypeEnum componentType = containerV.getType();
99         Map<String, MapPropertiesDataDefinition> instanceProperties = null;
100         if (componentType == ComponentTypeEnum.RESOURCE) {
101             Either<GraphVertex, JanusGraphOperationStatus> subcategoryV = janusGraphDao
102                 .getChildVertex(containerV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
103             if (subcategoryV.isRight()) {
104                 log.debug("Failed to fetch category vertex for resource {} error {}  ", containerV.getUniqueId(), subcategoryV.right().value());
105                 return StorageOperationStatus.GENERAL_ERROR;
106             }
107             GraphVertex catV = subcategoryV.left().value();
108             Map<GraphPropertyEnum, Object> metadataProperties = catV.getMetadataProperties();
109
110             String name = (String) metadataProperties.get(GraphPropertyEnum.NAME);
111             if (name.equals(ALLOTTED_CATEGORY)) {
112                 log.debug("Find allotted  resource {}.", containerV.getUniqueId());
113                 needConnectAllotted = true;
114                 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> instProperties = getInstProperties(containerV);
115                 if ( instProperties.isRight() ){
116                     return instProperties.right().value();
117                 }
118                 instanceProperties = instProperties.left().value();
119             }
120         }
121         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
122         if (jsonComposition != null && !jsonComposition.isEmpty()) {
123             try {
124                 status = connectInstances(containerV, needConnectAllotted, instanceProperties, jsonComposition);
125
126             } finally {
127                 if (status == StorageOperationStatus.OK) {
128                     janusGraphDao.commit();
129                 } else {
130                     janusGraphDao.rollback();
131                 }
132             }
133         }
134         return status;
135     }
136
137     private Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> getInstProperties(GraphVertex containerV) {
138         Map<String, MapPropertiesDataDefinition> instanceProperties;
139        Either<GraphVertex, JanusGraphOperationStatus> instProps = janusGraphDao
140            .getChildVertex(containerV, EdgeLabelEnum.INST_PROPERTIES, JsonParseFlagEnum.ParseAll);
141       
142         if (instProps.isRight()) {
143             if (instProps.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
144                 instanceProperties = new HashMap<>();
145             } else {
146                 log.debug("Failed to fetch instance properties vertex for resource {} error {}  ", containerV.getUniqueId(), instProps.right().value());
147                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
148             }
149         } else {
150             instanceProperties = (Map<String, MapPropertiesDataDefinition>) instProps.left().value().getJson();
151         }
152         return Either.left(instanceProperties);
153     }
154
155     private StorageOperationStatus connectInstances(GraphVertex containerV, boolean needConnectAllotted, Map<String, MapPropertiesDataDefinition> instanceProperties,
156             Map<String, CompositionDataDefinition> jsonComposition) {
157         StorageOperationStatus status = StorageOperationStatus.OK;
158         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
159         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
160         for (Map.Entry<String, ComponentInstanceDataDefinition> entry : componentInstances.entrySet()) {
161             status = handleInstance(containerV, needConnectAllotted, instanceProperties, entry);
162             if ( status != StorageOperationStatus.OK){
163                 if ( status == StorageOperationStatus.NOT_FOUND ){
164                     log.debug("reset status and continue");
165                     status = StorageOperationStatus.OK;
166                 }else{
167                     log.debug("Failed handle instance. exit");
168                     break;
169                 }
170             }
171         }
172         return status;
173     }
174
175     private StorageOperationStatus handleInstance(GraphVertex containerV, boolean needConnectAllotted, Map<String, MapPropertiesDataDefinition> instanceProperties, Map.Entry<String, ComponentInstanceDataDefinition> entry) {
176         ComponentInstanceDataDefinition instance = entry.getValue();
177         StorageOperationStatus status = nodeTemplateOperation.createInstanceEdge(containerV, instance);
178         if (status != StorageOperationStatus.OK) {
179             if ( status == StorageOperationStatus.NOT_FOUND ){
180                 Boolean highest = (Boolean) containerV.getMetadataProperties().get(GraphPropertyEnum.IS_HIGHEST_VERSION);
181                 log.debug("No origin for instance {} with ID {}. The component is highest ={},  Reset status and continue.. ", instance.getUniqueId(), instance.getComponentUid(), highest);
182                 status = StorageOperationStatus.OK;
183             }else{
184                 log.debug("Failed to connect in container {} instance {} to origin {} error {}  ", containerV.getUniqueId(), instance.getUniqueId(), instance.getComponentUid(), status);
185                 return status;
186             }
187         }
188         if (needConnectAllotted) {
189             status = connectAllotedInstances(containerV, instanceProperties, instance);
190         }
191         return status;
192     }
193
194     private StorageOperationStatus connectAllotedInstances(GraphVertex containerV, Map<String, MapPropertiesDataDefinition> instanceProperties, ComponentInstanceDataDefinition instance) {
195         StorageOperationStatus status = StorageOperationStatus.OK;
196         if ( instanceProperties != null ){
197             MapPropertiesDataDefinition mapPropertiesDataDefinition = instanceProperties.get(instance.getUniqueId());
198             if ( mapPropertiesDataDefinition != null ){
199                 status = checkAllottedPropertyAndConnect(containerV, instance, mapPropertiesDataDefinition);
200             }else{
201                 log.debug("No isntances properties for instance {}", instance.getUniqueId());
202             }
203         }
204         return status;
205     }
206
207     private StorageOperationStatus checkAllottedPropertyAndConnect(GraphVertex containerV, ComponentInstanceDataDefinition instance, MapPropertiesDataDefinition mapPropertiesDataDefinition) {
208         Map<String, PropertyDataDefinition> mapToscaDataDefinition = mapPropertiesDataDefinition.getMapToscaDataDefinition();
209         StorageOperationStatus status = StorageOperationStatus.OK;
210         Optional<Entry<String, PropertyDataDefinition>> findFirst = mapToscaDataDefinition
211                 .entrySet()
212                 .stream()
213                 .filter(e -> UUID_PROPS_NAMES.contains(e.getKey()))
214                 .findFirst();
215         
216         if ( findFirst.isPresent() ){
217             PropertyDataDefinition property = findFirst.get().getValue();
218             String serviceUUID = property.getValue(); 
219             if ( serviceUUID != null ){
220                 log.debug("Defined reference service on property {} value {} on instance {}", property.getName(), property.getValue(), instance.getUniqueId() );
221                 status = nodeTemplateOperation.createAllottedOfEdge(containerV.getUniqueId(), instance.getUniqueId(), serviceUUID);
222                 if ( status != StorageOperationStatus.OK ){
223                     if ( status == StorageOperationStatus.NOT_FOUND ){
224                         Boolean highest = (Boolean) containerV.getMetadataProperties().get(GraphPropertyEnum.IS_HIGHEST_VERSION);
225                         log.debug("No origin for allotted reference {} with UUID {}. the component highest = {}, Reset status and continue.. ", instance.getUniqueId(), serviceUUID, highest);
226                         status = StorageOperationStatus.OK;
227                     }else{
228                         log.debug("Failed to connect in container {} instance {} to allotted service {} error {}  ", containerV.getUniqueId(), instance.getUniqueId(), instance.getComponentUid(), status);
229                         return status;
230                     }
231                 }
232             }else{
233                 log.debug("No value for property {} on instance {}", property.getName(),instance.getUniqueId() );
234             }
235         }else{
236             log.debug("No sercific properties of dependencies for instance {}", instance.getUniqueId());
237         }
238         return status;
239     }
240
241 }