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