2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.asdctool.impl;
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;
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;
51 import static java.util.Collections.emptyList;
52 import static java.util.stream.Collectors.toList;
54 @org.springframework.stereotype.Component("vrfObjectFixHandler")
55 public class VrfObjectFixHandler {
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",
62 "CONTAINER UNIQUE ID",
64 "INSTANCE UNIQUE ID"};
66 private XlsOutputHandler outputHandler;
67 private final String sheetName = this.getClass().getSimpleName() + "Report";
69 private JanusGraphDao janusGraphDao;
71 public VrfObjectFixHandler(JanusGraphDao janusGraphDao) {
72 this.janusGraphDao = janusGraphDao;
75 public boolean handle(String mode, String outputPath) {
76 outputHandler = new XlsOutputHandler(outputPath, sheetName, outputTableTitle);
79 return detectCorruptedData();
81 return fixCorruptedData();
83 log.debug("#handle - The invalid mode parameter has been received: {}", mode);
88 private boolean fixCorruptedData(){
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);
102 private boolean detectCorruptedData(){
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);
113 private void fixCorruptedVfrObjectAndRelatedInstances(GraphVertex vfrObjectV, Map<Vertex, List<ComponentInstanceDataDefinition>> instances) {
114 fixCorruptedVfrObject(vfrObjectV);
115 instances.forEach(this::fixCorruptedContainerInstances);
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);
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;
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);
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));
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()
155 .filter(i->ids.contains(i.getUniqueId()))
160 private void fixCorruptedContainerInstances(Vertex container, List<ComponentInstanceDataDefinition> corruptedInstances){
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);
171 private void fixComponentToscaName(List<ComponentInstanceDataDefinition> corruptedInstances, Map<String, ? extends ToscaDataDefinition> jsonObj) {
172 List<String> ids = corruptedInstances
174 .map(ComponentInstanceDataDefinition::getUniqueId)
177 CompositionDataDefinition composition = (CompositionDataDefinition)jsonObj.get(JsonConstantKeysEnum.COMPOSITION.getValue());
178 composition.getComponentInstances()
181 .filter(i->ids.contains(i.getUniqueId()))
182 .forEach(i->i.setToscaComponentName(VALID_TOSCA_NAME));
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);
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);
197 outputHandler.addRecord("CORRUPTED VRF OBJECT NOT FOUND");
199 outputHandler.writeOutputAndCloseFile();
203 private List<GraphVertex> rightOnGet(JanusGraphOperationStatus status) {
204 if(status == JanusGraphOperationStatus.NOT_FOUND){
207 throw new StorageException(status);
209 private GraphVertex rightOnUpdate(JanusGraphOperationStatus status) {
210 throw new StorageException(status);
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);
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()));