Upgrade SDC from Titan to Janus Graph
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / impl / VrfObjectFixHandler.java
1 package org.openecomp.sdc.asdctool.impl;
2
3 import org.apache.commons.collections.CollectionUtils;
4 import org.apache.commons.collections.MapUtils;
5 import org.apache.tinkerpop.gremlin.structure.Direction;
6 import org.apache.tinkerpop.gremlin.structure.Edge;
7 import org.apache.tinkerpop.gremlin.structure.Vertex;
8 import org.openecomp.sdc.asdctool.migration.tasks.handlers.XlsOutputHandler;
9 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
10 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
11 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
12 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
13 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
14 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
15 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
16 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
17 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
18 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
19 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
20 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
21 import org.openecomp.sdc.be.model.operations.StorageException;
22 import org.openecomp.sdc.common.log.wrappers.Logger;
23
24 import java.io.IOException;
25 import java.util.*;
26
27 import static java.util.Collections.emptyList;
28 import static java.util.stream.Collectors.toList;
29
30 @org.springframework.stereotype.Component("vrfObjectFixHandler")
31 public class VrfObjectFixHandler {
32
33     private static final Logger log = Logger.getLogger(VrfObjectFixHandler.class);
34     private static final String VALID_TOSCA_NAME = "org.openecomp.nodes.VRFObject";
35     private static final Object[] outputTableTitle =
36             new String[]{"VRF OBJECT VERSION",
37                     "CONTAINER NAME",
38                     "CONTAINER UNIQUE ID",
39                     "INSTANCE NAME",
40                     "INSTANCE UNIQUE ID"};
41
42     private XlsOutputHandler outputHandler;
43     private final String sheetName = this.getClass().getSimpleName() + "Report";
44
45     private JanusGraphDao janusGraphDao;
46
47     public VrfObjectFixHandler(JanusGraphDao janusGraphDao) {
48         this.janusGraphDao = janusGraphDao;
49     }
50
51     public boolean handle(String mode, String outputPath) {
52         outputHandler = new XlsOutputHandler(outputPath, sheetName, outputTableTitle);
53         switch (mode){
54             case "detect" :
55                 return detectCorruptedData();
56             case "fix":
57                 return fixCorruptedData();
58             default :
59                 log.debug("#handle - The invalid mode parameter has been received: {}", mode);
60                 return false;
61         }
62     }
63
64     private boolean fixCorruptedData(){
65         try{
66             Map<GraphVertex,Map<Vertex, List<ComponentInstanceDataDefinition>>> corruptedData = fetchCorruptedData();
67             corruptedData.forEach(this::fixCorruptedVfrObjectAndRelatedInstances);
68             janusGraphDao.commit();
69             writeOutput(corruptedData);
70         } catch (Exception e){
71             janusGraphDao.rollback();
72             log.debug("#fixCorruptedData - Failed to detect corrupted data. The exception occurred: ", e);
73             return false;
74         }
75         return true;
76     }
77
78     private boolean detectCorruptedData(){
79         try{
80             Map<GraphVertex,Map<Vertex, List<ComponentInstanceDataDefinition>>> corruptedData = fetchCorruptedData();
81             writeOutput(corruptedData);
82         } catch (Exception e){
83             log.debug("#detectCorruptedData - Failed to detect corrupted data. The exception occurred: ", e);
84             return false;
85         }
86         return true;
87     }
88
89     private void fixCorruptedVfrObjectAndRelatedInstances(GraphVertex vfrObjectV, Map<Vertex, List<ComponentInstanceDataDefinition>> instances) {
90         fixCorruptedVfrObject(vfrObjectV);
91         instances.forEach(this::fixCorruptedContainerInstances);
92     }
93
94     private void fixCorruptedVfrObject(GraphVertex vfrObjectV) {
95         vfrObjectV.getMetadataProperties().put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, VALID_TOSCA_NAME);
96         janusGraphDao.updateVertex(vfrObjectV).left().on(this::rightOnUpdate);
97     }
98
99     private Map<GraphVertex,Map<Vertex,List<ComponentInstanceDataDefinition>>> fetchCorruptedData(){
100         Map<GraphVertex,Map<Vertex, List<ComponentInstanceDataDefinition>>> corruptedData = new HashMap<>();
101         List<GraphVertex> vrfObjectsV = getCorruptedVrfObjects();
102         vrfObjectsV.forEach(vrfObjectV-> fillCorruptedData(vrfObjectV, corruptedData));
103         return corruptedData;
104     }
105
106     private List<GraphVertex> getCorruptedVrfObjects() {
107         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
108         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, "org.openecomp.resource.configuration.VRFObject");
109         return janusGraphDao.getByCriteria(VertexTypeEnum.NODE_TYPE, props).left().on(this::rightOnGet);
110     }
111
112     private void fillCorruptedData(GraphVertex vrfObjectV, Map<GraphVertex, Map<Vertex, List<ComponentInstanceDataDefinition>>> findToUpdate) {
113         Map<Vertex, List<ComponentInstanceDataDefinition>> corruptedInstances = new HashMap<>();
114         findToUpdate.put(vrfObjectV, corruptedInstances);
115         Iterator<Edge> instanceEdges = vrfObjectV.getVertex().edges(Direction.IN, EdgeLabelEnum.INSTANCE_OF.name());
116         while(instanceEdges.hasNext()){
117             Edge edge = instanceEdges.next();
118             putCorruptedInstances(corruptedInstances, edge, (List<String>) janusGraphDao
119                 .getProperty(edge, EdgePropertyEnum.INSTANCES));
120         }
121     }
122
123     private void putCorruptedInstances(Map<Vertex, List<ComponentInstanceDataDefinition>> corruptedInstances, Edge edge, List<String> ids) {
124         if(CollectionUtils.isNotEmpty(ids)){
125             Vertex container = edge.outVertex();
126             Map<String, ? extends ToscaDataDefinition> jsonObj = getJsonMap(container);
127             CompositionDataDefinition composition = (CompositionDataDefinition)jsonObj.get(JsonConstantKeysEnum.COMPOSITION.getValue());
128             corruptedInstances.put(container, composition.getComponentInstances()
129                     .values()
130                     .stream()
131                     .filter(i->ids.contains(i.getUniqueId()))
132                     .collect(toList()));
133         }
134     }
135
136     private void fixCorruptedContainerInstances(Vertex container, List<ComponentInstanceDataDefinition> corruptedInstances){
137         try {
138             Map jsonObj = getJsonMap(container);
139             fixComponentToscaName(corruptedInstances, jsonObj);
140             String jsonMetadataStr = JsonParserUtils.toJson(jsonObj);
141             container.property(GraphPropertyEnum.JSON.getProperty(), jsonMetadataStr);
142         } catch (IOException e) {
143             throw new StorageException("Failed to fix the corrupted instances of the container", e, JanusGraphOperationStatus.GENERAL_ERROR);
144         }
145     }
146
147     private void fixComponentToscaName(List<ComponentInstanceDataDefinition> corruptedInstances, Map<String, ? extends ToscaDataDefinition> jsonObj) {
148         List<String> ids = corruptedInstances
149                 .stream()
150                 .map(ComponentInstanceDataDefinition::getUniqueId)
151                 .collect(toList());
152
153         CompositionDataDefinition composition = (CompositionDataDefinition)jsonObj.get(JsonConstantKeysEnum.COMPOSITION.getValue());
154         composition.getComponentInstances()
155                 .values()
156                 .stream()
157                 .filter(i->ids.contains(i.getUniqueId()))
158                 .forEach(i->i.setToscaComponentName(VALID_TOSCA_NAME));
159     }
160
161     private Map getJsonMap(Vertex container) {
162         String json = (String)container.property(GraphPropertyEnum.JSON.getProperty()).value();
163         Map<GraphPropertyEnum, Object> properties = janusGraphDao.getVertexProperties(container);
164         VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
165         return JsonParserUtils.toMap(json, label != null ? label.getClassOfJson() : null);
166     }
167
168     private void writeOutput(Map<GraphVertex, Map<Vertex, List<ComponentInstanceDataDefinition>>> corruptedData) {
169         if(outputHandler.getOutputPath() != null){
170             if(MapUtils.isNotEmpty(corruptedData)){
171                 corruptedData.forEach(this::addVrfObjectRecord);
172             } else {
173                 outputHandler.addRecord("CORRUPTED VRF OBJECT NOT FOUND");
174             }
175             outputHandler.writeOutputAndCloseFile();
176         }
177     }
178
179     private List<GraphVertex> rightOnGet(JanusGraphOperationStatus status) {
180         if(status == JanusGraphOperationStatus.NOT_FOUND){
181             return emptyList();
182         }
183         throw new StorageException(status);
184     }
185     private GraphVertex rightOnUpdate(JanusGraphOperationStatus status) {
186         throw new StorageException(status);
187     }
188
189     private void addVrfObjectRecord(GraphVertex vrfObject, Map<Vertex, List<ComponentInstanceDataDefinition>> instances) {
190         outputHandler.addRecord(vrfObject.getMetadataProperties().get(GraphPropertyEnum.VERSION).toString());
191         instances.forEach(this::addVrfObjectInstances);
192     }
193
194     private void addVrfObjectInstances(Vertex container, List<ComponentInstanceDataDefinition> instances) {
195         outputHandler.addRecord("", container.property(GraphPropertyEnum.NAME.getProperty()).value().toString(), container.property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value().toString());
196         instances.forEach(i->outputHandler.addRecord("","","",i.getName(),i.getUniqueId()));
197     }
198 }