aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java')
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java292
1 files changed, 292 insertions, 0 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java
new file mode 100644
index 0000000000..3f2b41e3b5
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ArchiveOperation.java
@@ -0,0 +1,292 @@
+package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+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.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
+import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArchiveOperation.Action.ARCHIVE;
+import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArchiveOperation.Action.RESTORE;
+
+/**
+ * Created by yavivi on 25/03/2018.
+ */
+@Component
+public class ArchiveOperation extends BaseOperation {
+
+ private static final Logger log = Logger.getLogger(ArchiveOperation.class.getName());
+
+ @Autowired
+ private IGraphLockOperation graphLockOperation;
+
+ public enum Action {
+ ARCHIVE, RESTORE;
+ }
+
+ public ArchiveOperation(JanusGraphDao janusGraphDao, IGraphLockOperation graphLockOperation){
+ this.janusGraphDao = janusGraphDao;
+ this.graphLockOperation = graphLockOperation;
+ }
+
+ public Either<List<String>, ActionStatus> archiveComponent(String componentId) {
+ final Either<GraphVertex, JanusGraphOperationStatus> vertexResult = this.janusGraphDao.getVertexById(componentId);
+ if (vertexResult.isLeft()){
+ return doAction(ARCHIVE, vertexResult.left().value());
+ } else {
+ return Either.right(onError(ARCHIVE.name(), componentId, vertexResult.right().value()));
+ }
+ }
+
+ public Either<List<String>, ActionStatus> restoreComponent(String componentId) {
+ final Either<GraphVertex, JanusGraphOperationStatus> vertexResult = this.janusGraphDao.getVertexById(componentId);
+ if (vertexResult.isLeft()){
+ return doAction(RESTORE, vertexResult.left().value());
+ } else {
+ return Either.right(onError(RESTORE.name(), componentId, vertexResult.right().value()));
+ }
+ }
+
+ public ActionStatus onVspRestored(String csarId){
+ return onVspStateChanged(RESTORE, csarId);
+ }
+
+ public ActionStatus onVspArchived(String csarId){
+ return onVspStateChanged(ARCHIVE, csarId);
+ }
+
+ private ActionStatus onVspStateChanged(Action action, String csarId) {
+ Map<GraphPropertyEnum, Object> props = new HashMap<>();
+ props.put(GraphPropertyEnum.CSAR_UUID, csarId);
+ Either<List<GraphVertex>, JanusGraphOperationStatus> vfsE = janusGraphDao
+ .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props);
+ return vfsE.either(vList -> setVspArchived(action, vList), s -> onError("VSP_"+action.name(), csarId, s));
+ }
+
+ private ActionStatus setVspArchived(Action action, List<GraphVertex> vList) {
+ if (!vList.isEmpty()) {
+ //Find & Lock the highest version component
+ GraphVertex highestVersion = this.getHighestVersionFrom(vList.get(0));
+ StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+ if (lockStatus != StorageOperationStatus.OK){
+ return onError(action.name(), highestVersion.getUniqueId(), JanusGraphOperationStatus.ALREADY_LOCKED);
+ }
+
+ try {
+ //Set isVspArchived flag
+ for (GraphVertex v : vList) {
+ boolean val = action == ARCHIVE ? true : false;
+ v.setJsonMetadataField(JsonPresentationFields.IS_VSP_ARCHIVED, val);
+ v.addMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED, val);
+ janusGraphDao.updateVertex(v);
+ }
+ return commitAndCheck("VSP_"+action.name(), vList.toString());
+ } finally {
+ this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+ }
+
+ }
+ return ActionStatus.OK;
+ }
+
+ public List<String> setArchivedOriginsFlagInComponentInstances(GraphVertex compositionService) {
+ List<String> ciUidsWithArchivedOrigins = new LinkedList();
+ Either<List<GraphVertex>, JanusGraphOperationStatus> instanceOfVerticesE = janusGraphDao
+ .getChildrenVertecies(compositionService, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.NoParse);
+ Either<List<GraphVertex>, JanusGraphOperationStatus> proxyOfVerticesE = janusGraphDao
+ .getChildrenVertecies(compositionService, EdgeLabelEnum.PROXY_OF, JsonParseFlagEnum.NoParse);
+
+ List<GraphVertex> all = new LinkedList<>();
+ if (instanceOfVerticesE.isLeft()){
+ all.addAll(instanceOfVerticesE.left().value());
+ }
+ if (proxyOfVerticesE.isLeft()){
+ all.addAll(proxyOfVerticesE.left().value());
+ }
+
+ List<GraphVertex> archivedOrigins = all.stream().filter(v -> Boolean.TRUE.equals(v.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED))).collect(Collectors.toList());
+ List<String> archivedOriginsUids = archivedOrigins.stream().map(GraphVertex::getUniqueId).collect(Collectors.toList());
+
+ Map<String, CompositionDataDefinition> compositionsJson = (Map<String, CompositionDataDefinition>) compositionService.getJson();
+
+ if (compositionsJson != null) {
+ CompositionDataDefinition composition = compositionsJson.get(JsonConstantKeysEnum.COMPOSITION.getValue());
+ if (composition != null) {
+
+ //Get all component instances from composition
+ Map<String, ComponentInstanceDataDefinition> componentInstances = composition.getComponentInstances();
+
+ //Extract component instances uids that has archived origins
+ ciUidsWithArchivedOrigins = componentInstances.
+ values().
+ stream().
+ //filter CIs whose origins are marked as archived (componentUid is in archivedOriginsUids) the second condition handles the PROXY_OF case)
+ filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
+ map(ComponentInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
+
+ //set archived origins flag
+ componentInstances.
+ values().
+ stream().
+ filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
+ forEach( ci -> ci.setOriginArchived(true));
+
+ }
+ }
+
+ return ciUidsWithArchivedOrigins;
+ }
+
+ private Either<List<String>, ActionStatus> doAction(Action action, GraphVertex componentVertex){
+
+ GraphVertex highestVersion = this.getHighestVersionFrom(componentVertex);
+
+ if (action.equals(ARCHIVE) && isInCheckoutState(highestVersion)) {
+ return Either.right(ActionStatus.INVALID_SERVICE_STATE);
+ }
+
+ //Lock the Highest Version
+ StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+ if (lockStatus != StorageOperationStatus.OK){
+ return Either.right(onError(action.name(), componentVertex.getUniqueId(), JanusGraphOperationStatus.ALREADY_LOCKED));
+ }
+
+ //Refetch latest version with full parsing
+ highestVersion = this.janusGraphDao
+ .getVertexById(highestVersion.getUniqueId(), JsonParseFlagEnum.ParseAll).left().value();
+
+ try {
+ //Get Catalog and Archive Roots
+ GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT).left().value();
+ GraphVertex archiveRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.ARCHIVE_ROOT).left().value();
+
+ if (action == ARCHIVE) {
+ archiveEdges(catalogRoot, archiveRoot, highestVersion);
+ } else if (action == RESTORE) {
+ restoreEdges(catalogRoot, archiveRoot, highestVersion);
+ }
+ setPropertiesByAction(highestVersion, action);
+ janusGraphDao.updateVertex(highestVersion);
+
+ List<String> affectedComponentIds = handleParents(highestVersion, catalogRoot, archiveRoot, action);
+ ActionStatus sc = commitAndCheck(action.name(), highestVersion.getUniqueId());
+ return sc == ActionStatus.OK ? Either.left(affectedComponentIds) : Either.right(sc);
+ } finally {
+ this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
+ }
+ }
+
+ private ActionStatus commitAndCheck(String action, String componentId) {
+ JanusGraphOperationStatus status = janusGraphDao.commit();
+ if (!status.equals(JanusGraphOperationStatus.OK)){
+ return onError(action, componentId, status);
+ }
+ return ActionStatus.OK;
+ }
+
+ private boolean isInCheckoutState(GraphVertex v) {
+ if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name().equals(v.getMetadataProperty(GraphPropertyEnum.STATE))){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Walks on children until highest version is reached
+ * @param v
+ * @return
+ */
+ private GraphVertex getHighestVersionFrom(GraphVertex v) {
+ Either<GraphVertex, JanusGraphOperationStatus> childVertexE = janusGraphDao
+ .getChildVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
+ GraphVertex highestVersionVertex = v;
+
+ while (childVertexE.isLeft()) {
+ highestVersionVertex = childVertexE.left().value();
+ childVertexE = janusGraphDao
+ .getChildVertex(highestVersionVertex, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
+ }
+ return highestVersionVertex;
+ }
+
+ private boolean isHighestVersion(GraphVertex v){
+ Boolean highest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
+ return highest != null && highest;
+ }
+
+ private List<String> handleParents(GraphVertex v, GraphVertex catalogRoot, GraphVertex archiveRoot, Action action) {
+ Either<GraphVertex, JanusGraphOperationStatus> parentVertexE = janusGraphDao
+ .getParentVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+ List<String> affectedCompIds = new ArrayList();
+ affectedCompIds.add(v.getUniqueId());
+
+ while (parentVertexE.isLeft()){
+ GraphVertex cv = parentVertexE.left().value();
+ affectedCompIds.add(cv.getUniqueId());
+ boolean isHighestVersion = isHighestVersion(cv);
+ if (isHighestVersion){
+ if (action == ARCHIVE) {
+ archiveEdges(catalogRoot, archiveRoot, cv);
+ } else {
+ restoreEdges(catalogRoot, archiveRoot, cv);
+ }
+ }
+ setPropertiesByAction(cv, action);
+ janusGraphDao.updateVertex(cv);
+ parentVertexE = janusGraphDao
+ .getParentVertex(cv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
+ }
+ return affectedCompIds;
+ }
+
+ private void archiveEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
+ janusGraphDao.deleteAllEdges(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT);
+ janusGraphDao.createEdge(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT, null);
+ setPropertiesByAction(v, ARCHIVE);
+ }
+
+ private void restoreEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
+ janusGraphDao.deleteAllEdges(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT);
+ janusGraphDao.createEdge(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT, null);
+ setPropertiesByAction(v, RESTORE);
+ }
+
+ private void setPropertiesByAction(GraphVertex v, Action action) {
+ long now = System.currentTimeMillis();
+
+ boolean isArchived = action == ARCHIVE ? true : false;
+ v.addMetadataProperty(GraphPropertyEnum.IS_ARCHIVED, isArchived);
+ v.addMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME, now);
+ v.setJsonMetadataField(JsonPresentationFields.IS_ARCHIVED, isArchived);
+ v.setJsonMetadataField(JsonPresentationFields.ARCHIVE_TIME, now);
+ }
+
+ private ActionStatus onError(String action, String componentId, JanusGraphOperationStatus s) {
+ ActionStatus ret = ActionStatus.GENERAL_ERROR;
+ if (s == JanusGraphOperationStatus.NOT_FOUND){
+ ret = ActionStatus.RESOURCE_NOT_FOUND;
+ } else if (s == JanusGraphOperationStatus.ALREADY_LOCKED) {
+ ret = ActionStatus.COMPONENT_IN_USE;
+ }
+ String retCodeVal = ret.name();
+ log.error("error occurred when trying to {} {}. Return code is: {}", action, componentId, retCodeVal);
+ return ret;
+ }
+}