/*- * ============LICENSE_START======================================================= * SDC * ================================================================================ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import fj.data.Either; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; import org.janusgraph.core.JanusGraphVertex; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition; import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.model.ComponentDependency; import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.common.log.wrappers.Logger; import org.springframework.stereotype.Component; @Component public class UpgradeOperation extends BaseOperation { private static final Logger log = Logger.getLogger(UpgradeOperation.class.getName()); public Either, StorageOperationStatus> getComponentDependencies(String componentId) { Either vertexById = janusGraphDao.getVertexById(componentId); if (vertexById.isRight()) { log.debug("Failed to fetch vertex with id {} error {}", componentId, vertexById.right().value()); return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value())); } List dependencies = new ArrayList<>(); GraphVertex vertex = vertexById.left().value(); StorageOperationStatus status = fillDependenciesByVertex(componentId, dependencies, vertex); if (status != StorageOperationStatus.OK) { return Either.right(status); } GraphVertex vertexToStart = vertex; Function> getNextElement = vertexP -> janusGraphDao .getParentVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll); status = handleVersionChain(componentId, dependencies, vertex, getNextElement); if (status != StorageOperationStatus.OK) { return Either.right(status); } vertex = vertexToStart; getNextElement = vertexP -> janusGraphDao.getChildVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll); status = handleVersionChain(componentId, dependencies, vertex, getNextElement); return status == StorageOperationStatus.OK ? Either.left(dependencies) : Either.right(status); } private StorageOperationStatus handleVersionChain(String componentId, List dependencies, GraphVertex vertexToStart, Function> getNextElement) { StorageOperationStatus status; boolean nextInChain = true; GraphVertex vertex = vertexToStart; Either nextInChainV; while (nextInChain) { nextInChainV = getNextElement.apply(vertex); if (nextInChainV.isRight()) { nextInChain = false; } else { vertex = nextInChainV.left().value(); status = fillDependenciesByVertex(componentId, dependencies, vertex); if (status != StorageOperationStatus.OK) { return status; } } } return StorageOperationStatus.OK; } private StorageOperationStatus fillDependenciesByVertex(String componentId, List dependencies, GraphVertex vertex) { StorageOperationStatus status = StorageOperationStatus.OK; if (needToAddToDependency(vertex)) { ComponentDependency dependency = fillDataFromVertex(vertex, null, null); List dependList = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF); for (EdgeLabelEnum label : dependList) { status = fillDependenciesByLabel(componentId, vertex, dependency, label); if (status != StorageOperationStatus.OK) { log.debug("Failed to create dependencies for component {} and label {} status {}", componentId, label, status); break; } } if (status == StorageOperationStatus.OK) { dependencies.add(dependency); } } return status; } private boolean needToAddToDependency(GraphVertex vertex) { Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED); Boolean isArchived = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED); return !Boolean.TRUE.equals(isDeleted) && !Boolean.TRUE.equals(isArchived); } private StorageOperationStatus fillDependenciesByLabel(String componentId, GraphVertex vertex, ComponentDependency dependency, EdgeLabelEnum label) { Either, JanusGraphOperationStatus> parentVertices = janusGraphDao .getParentVertices(vertex, label, JsonParseFlagEnum.ParseAll); if (parentVertices.isRight() && parentVertices.right().value() != JanusGraphOperationStatus.NOT_FOUND) { log.debug("Failed to fetch parent verticies by label INSTANCE_OF for vertex with id {} error {}", componentId, parentVertices.right().value()); return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(parentVertices.right().value()); } if (parentVertices.isLeft()) { List existIn = new ArrayList<>(); parentVertices.left().value().forEach(v -> handleHighestVersion(vertex, label, existIn, v)); dependency.addDependencies(existIn); } return StorageOperationStatus.OK; } private void handleHighestVersion(GraphVertex vertexOrigin, EdgeLabelEnum label, List exisIn, GraphVertex containerVertex) { Boolean isHighest = (Boolean) containerVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION); if (isHighest && needToAddToDependency(containerVertex)) { JanusGraphVertex janusGraphVertex = containerVertex.getVertex(); Iterator edges = janusGraphVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name()); //verify that it is a last version - highest by version number if (edges == null || !edges.hasNext()) { ComponentDependency container = fillDataFromVertex(containerVertex, vertexOrigin.getUniqueId(), label); boolean addToDependency = true; if (label == EdgeLabelEnum.ALLOTTED_OF) { //in case of not full allotted chain not add to dependency list addToDependency = findAllottedChain(containerVertex, container); } if (addToDependency) { exisIn.add(container); } } } } private boolean findAllottedChain(GraphVertex vertex, ComponentDependency container) { Either, JanusGraphOperationStatus> parentVertecies = janusGraphDao .getParentVertices(vertex, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.ParseAll); if (parentVertecies.isLeft()) { List existIn = new ArrayList<>(); parentVertecies.left().value().forEach(v -> { Boolean isHighest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION); if (isHighest && needToAddToDependency(v)) { JanusGraphVertex janusGraphVertex = v.getVertex(); Iterator edges = janusGraphVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name()); //verify that it is a last version - highest by version number if (edges == null || !edges.hasNext()) { ComponentDependency parentContainer = fillDataFromVertex(v, vertex.getUniqueId(), EdgeLabelEnum.INSTANCE_OF); existIn.add(parentContainer); } } }); if (!existIn.isEmpty()) { container.setDependencies(existIn); return true; } } return false; } private ComponentDependency fillDataFromVertex(GraphVertex v, String originId, EdgeLabelEnum edgeLabel) { ComponentDependency container = new ComponentDependency(); container.setName((String) v.getMetadataProperty(GraphPropertyEnum.NAME)); container.setVersion((String) v.getMetadataProperty(GraphPropertyEnum.VERSION)); container.setUniqueId(v.getUniqueId()); container.setType((String) v.getMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE)); container.setIcon((String) v.getJsonMetadataField(JsonPresentationFields.ICON)); container.setState((String) v.getMetadataProperty(GraphPropertyEnum.STATE)); if (edgeLabel == EdgeLabelEnum.PROXY_OF || edgeLabel == EdgeLabelEnum.ALLOTTED_OF) { findInstanceNames(v, originId, edgeLabel, container); } return container; } private void findInstanceNames(GraphVertex v, String originId, EdgeLabelEnum edgeLabel, ComponentDependency container) { Map jsonComposition = (Map) v.getJson(); CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue()); JanusGraphVertex vertex = v.getVertex(); Iterator edges = vertex.edges(Direction.OUT, edgeLabel.name()); while (edges != null && edges.hasNext()) { Edge edge = edges.next(); JanusGraphVertex inVertex = (JanusGraphVertex) edge.inVertex(); String id = (String) janusGraphDao.getProperty(inVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()); if (id.equals(originId)) { List instanceOnEdge = (List) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES); Map componentInstances = compositionDataDefinition.getComponentInstances(); if (componentInstances != null) { List ciNames = componentInstances.values().stream().filter(ci -> instanceOnEdge.contains(ci.getUniqueId())) .map(ComponentInstanceDataDefinition::getName).collect(Collectors.toList()); if (ciNames != null && !ciNames.isEmpty()) { container.setInstanceNames(ciNames); break; } } } } } public List getInstanceIdFromAllottedEdge(String resourceId, String serviceInvariantUUID) { Either vertexById = janusGraphDao.getVertexById(resourceId); if (vertexById.isLeft()) { GraphVertex vertexG = vertexById.left().value(); JanusGraphVertex vertex = vertexG.getVertex(); Iterator edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name()); while (edges != null && edges.hasNext()) { Edge edge = edges.next(); JanusGraphVertex inVertex = (JanusGraphVertex) edge.inVertex(); String vertexInInvUUID = (String) janusGraphDao.getProperty(inVertex, GraphPropertyEnum.INVARIANT_UUID.getProperty()); if (vertexInInvUUID.equals(serviceInvariantUUID)) { return (List) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES); } } } return new ArrayList<>(); } }