re base code
[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.jsongraph.GraphVertex;
10 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
11 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
12 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
13 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
14 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
15 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
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.jsontitan.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 TitanDao titanDao;
46
47     public VrfObjectFixHandler(TitanDao titanDao) {
48         this.titanDao = titanDao;
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             titanDao.commit();
69             writeOutput(corruptedData);
70         } catch (Exception e){
71             titanDao.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         titanDao.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 titanDao.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>) titanDao.getProperty(edge, EdgePropertyEnum.INSTANCES));
119         }
120     }
121
122     private void putCorruptedInstances(Map<Vertex, List<ComponentInstanceDataDefinition>> corruptedInstances, Edge edge, List<String> ids) {
123         if(CollectionUtils.isNotEmpty(ids)){
124             Vertex container = edge.outVertex();
125             Map<String, ? extends ToscaDataDefinition> jsonObj = getJsonMap(container);
126             CompositionDataDefinition composition = (CompositionDataDefinition)jsonObj.get(JsonConstantKeysEnum.COMPOSITION.getValue());
127             corruptedInstances.put(container, composition.getComponentInstances()
128                     .values()
129                     .stream()
130                     .filter(i->ids.contains(i.getUniqueId()))
131                     .collect(toList()));
132         }
133     }
134
135     private void fixCorruptedContainerInstances(Vertex container, List<ComponentInstanceDataDefinition> corruptedInstances){
136         try {
137             Map jsonObj = getJsonMap(container);
138             fixComponentToscaName(corruptedInstances, jsonObj);
139             String jsonMetadataStr = JsonParserUtils.toJson(jsonObj);
140             container.property(GraphPropertyEnum.JSON.getProperty(), jsonMetadataStr);
141         } catch (IOException e) {
142             throw new StorageException("Failed to fix the corrupted instances of the container", e, TitanOperationStatus.GENERAL_ERROR);
143         }
144     }
145
146     private void fixComponentToscaName(List<ComponentInstanceDataDefinition> corruptedInstances, Map<String, ? extends ToscaDataDefinition> jsonObj) {
147         List<String> ids = corruptedInstances
148                 .stream()
149                 .map(ComponentInstanceDataDefinition::getUniqueId)
150                 .collect(toList());
151
152         CompositionDataDefinition composition = (CompositionDataDefinition)jsonObj.get(JsonConstantKeysEnum.COMPOSITION.getValue());
153         composition.getComponentInstances()
154                 .values()
155                 .stream()
156                 .filter(i->ids.contains(i.getUniqueId()))
157                 .forEach(i->i.setToscaComponentName(VALID_TOSCA_NAME));
158     }
159
160     private Map getJsonMap(Vertex container) {
161         String json = (String)container.property(GraphPropertyEnum.JSON.getProperty()).value();
162         Map<GraphPropertyEnum, Object> properties = titanDao.getVertexProperties(container);
163         VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
164         return JsonParserUtils.toMap(json, label != null ? label.getClassOfJson() : null);
165     }
166
167     private void writeOutput(Map<GraphVertex, Map<Vertex, List<ComponentInstanceDataDefinition>>> corruptedData) {
168         if(outputHandler.getOutputPath() != null){
169             if(MapUtils.isNotEmpty(corruptedData)){
170                 corruptedData.forEach(this::addVrfObjectRecord);
171             } else {
172                 outputHandler.addRecord("CORRUPTED VRF OBJECT NOT FOUND");
173             }
174             outputHandler.writeOutputAndCloseFile();
175         }
176     }
177
178     private List<GraphVertex> rightOnGet(TitanOperationStatus status) {
179         if(status == TitanOperationStatus.NOT_FOUND){
180             return emptyList();
181         }
182         throw new StorageException(status);
183     }
184     private GraphVertex rightOnUpdate(TitanOperationStatus status) {
185         throw new StorageException(status);
186     }
187
188     private void addVrfObjectRecord(GraphVertex vrfObject, Map<Vertex, List<ComponentInstanceDataDefinition>> instances) {
189         outputHandler.addRecord(vrfObject.getMetadataProperties().get(GraphPropertyEnum.VERSION).toString());
190         instances.forEach(this::addVrfObjectInstances);
191     }
192
193     private void addVrfObjectInstances(Vertex container, List<ComponentInstanceDataDefinition> instances) {
194         outputHandler.addRecord("", container.property(GraphPropertyEnum.NAME.getProperty()).value().toString(), container.property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value().toString());
195         instances.forEach(i->outputHandler.addRecord("","","",i.getName(),i.getUniqueId()));
196     }
197 }