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