1 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
4 import org.openecomp.sdc.be.dao.api.ActionStatus;
5 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
6 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
7 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
8 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
9 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
10 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
11 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
12 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
13 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
14 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
15 import org.openecomp.sdc.be.model.LifecycleStateEnum;
16 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
17 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
18 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
19 import org.openecomp.sdc.common.log.wrappers.Logger;
20 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.stereotype.Component;
24 import java.util.stream.Collectors;
26 import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArchiveOperation.Action.ARCHIVE;
27 import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArchiveOperation.Action.RESTORE;
30 * Created by yavivi on 25/03/2018.
33 public class ArchiveOperation extends BaseOperation {
35 private static final Logger log = Logger.getLogger(ArchiveOperation.class.getName());
38 private IGraphLockOperation graphLockOperation;
44 public ArchiveOperation(JanusGraphDao janusGraphDao, IGraphLockOperation graphLockOperation){
45 this.janusGraphDao = janusGraphDao;
46 this.graphLockOperation = graphLockOperation;
49 public Either<List<String>, ActionStatus> archiveComponent(String componentId) {
50 final Either<GraphVertex, JanusGraphOperationStatus> vertexResult = this.janusGraphDao.getVertexById(componentId);
51 if (vertexResult.isLeft()){
52 return doAction(ARCHIVE, vertexResult.left().value());
54 return Either.right(onError(ARCHIVE.name(), componentId, vertexResult.right().value()));
58 public Either<List<String>, ActionStatus> restoreComponent(String componentId) {
59 final Either<GraphVertex, JanusGraphOperationStatus> vertexResult = this.janusGraphDao.getVertexById(componentId);
60 if (vertexResult.isLeft()){
61 return doAction(RESTORE, vertexResult.left().value());
63 return Either.right(onError(RESTORE.name(), componentId, vertexResult.right().value()));
67 public ActionStatus onVspRestored(String csarId){
68 return onVspStateChanged(RESTORE, csarId);
71 public ActionStatus onVspArchived(String csarId){
72 return onVspStateChanged(ARCHIVE, csarId);
75 private ActionStatus onVspStateChanged(Action action, String csarId) {
76 Map<GraphPropertyEnum, Object> props = new HashMap<>();
77 props.put(GraphPropertyEnum.CSAR_UUID, csarId);
78 Either<List<GraphVertex>, JanusGraphOperationStatus> vfsE = janusGraphDao
79 .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props);
80 return vfsE.either(vList -> setVspArchived(action, vList), s -> onError("VSP_"+action.name(), csarId, s));
83 private ActionStatus setVspArchived(Action action, List<GraphVertex> vList) {
84 if (!vList.isEmpty()) {
85 //Find & Lock the highest version component
86 GraphVertex highestVersion = this.getHighestVersionFrom(vList.get(0));
87 StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
88 if (lockStatus != StorageOperationStatus.OK){
89 return onError(action.name(), highestVersion.getUniqueId(), JanusGraphOperationStatus.ALREADY_LOCKED);
93 //Set isVspArchived flag
94 for (GraphVertex v : vList) {
95 boolean val = action == ARCHIVE ? true : false;
96 v.setJsonMetadataField(JsonPresentationFields.IS_VSP_ARCHIVED, val);
97 v.addMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED, val);
98 janusGraphDao.updateVertex(v);
100 return commitAndCheck("VSP_"+action.name(), vList.toString());
102 this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
106 return ActionStatus.OK;
109 public List<String> setArchivedOriginsFlagInComponentInstances(GraphVertex compositionService) {
110 List<String> ciUidsWithArchivedOrigins = new LinkedList();
111 Either<List<GraphVertex>, JanusGraphOperationStatus> instanceOfVerticesE = janusGraphDao
112 .getChildrenVertecies(compositionService, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.NoParse);
113 Either<List<GraphVertex>, JanusGraphOperationStatus> proxyOfVerticesE = janusGraphDao
114 .getChildrenVertecies(compositionService, EdgeLabelEnum.PROXY_OF, JsonParseFlagEnum.NoParse);
116 List<GraphVertex> all = new LinkedList<>();
117 if (instanceOfVerticesE.isLeft()){
118 all.addAll(instanceOfVerticesE.left().value());
120 if (proxyOfVerticesE.isLeft()){
121 all.addAll(proxyOfVerticesE.left().value());
124 List<GraphVertex> archivedOrigins = all.stream().filter(v -> Boolean.TRUE.equals(v.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED))).collect(Collectors.toList());
125 List<String> archivedOriginsUids = archivedOrigins.stream().map(GraphVertex::getUniqueId).collect(Collectors.toList());
127 Map<String, CompositionDataDefinition> compositionsJson = (Map<String, CompositionDataDefinition>) compositionService.getJson();
129 if (compositionsJson != null) {
130 CompositionDataDefinition composition = compositionsJson.get(JsonConstantKeysEnum.COMPOSITION.getValue());
131 if (composition != null) {
133 //Get all component instances from composition
134 Map<String, ComponentInstanceDataDefinition> componentInstances = composition.getComponentInstances();
136 //Extract component instances uids that has archived origins
137 ciUidsWithArchivedOrigins = componentInstances.
140 //filter CIs whose origins are marked as archived (componentUid is in archivedOriginsUids) the second condition handles the PROXY_OF case)
141 filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
142 map(ComponentInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
144 //set archived origins flag
148 filter(ci -> archivedOriginsUids.contains(ci.getComponentUid()) || archivedOriginsUids.contains(ci.getToscaPresentationValue(JsonPresentationFields.CI_SOURCE_MODEL_UID))).
149 forEach( ci -> ci.setOriginArchived(true));
154 return ciUidsWithArchivedOrigins;
157 private Either<List<String>, ActionStatus> doAction(Action action, GraphVertex componentVertex){
159 GraphVertex highestVersion = this.getHighestVersionFrom(componentVertex);
161 if (action.equals(ARCHIVE) && isInCheckoutState(highestVersion)) {
162 return Either.right(ActionStatus.INVALID_SERVICE_STATE);
165 //Lock the Highest Version
166 StorageOperationStatus lockStatus = this.graphLockOperation.lockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
167 if (lockStatus != StorageOperationStatus.OK){
168 return Either.right(onError(action.name(), componentVertex.getUniqueId(), JanusGraphOperationStatus.ALREADY_LOCKED));
171 //Refetch latest version with full parsing
172 highestVersion = this.janusGraphDao
173 .getVertexById(highestVersion.getUniqueId(), JsonParseFlagEnum.ParseAll).left().value();
176 //Get Catalog and Archive Roots
177 GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT).left().value();
178 GraphVertex archiveRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.ARCHIVE_ROOT).left().value();
180 if (action == ARCHIVE) {
181 archiveEdges(catalogRoot, archiveRoot, highestVersion);
182 } else if (action == RESTORE) {
183 restoreEdges(catalogRoot, archiveRoot, highestVersion);
185 setPropertiesByAction(highestVersion, action);
186 janusGraphDao.updateVertex(highestVersion);
188 List<String> affectedComponentIds = handleParents(highestVersion, catalogRoot, archiveRoot, action);
189 ActionStatus sc = commitAndCheck(action.name(), highestVersion.getUniqueId());
190 return sc == ActionStatus.OK ? Either.left(affectedComponentIds) : Either.right(sc);
192 this.graphLockOperation.unlockComponent(highestVersion.getUniqueId(), highestVersion.getType().getNodeType());
196 private ActionStatus commitAndCheck(String action, String componentId) {
197 JanusGraphOperationStatus status = janusGraphDao.commit();
198 if (!status.equals(JanusGraphOperationStatus.OK)){
199 return onError(action, componentId, status);
201 return ActionStatus.OK;
204 private boolean isInCheckoutState(GraphVertex v) {
205 if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name().equals(v.getMetadataProperty(GraphPropertyEnum.STATE))){
212 * Walks on children until highest version is reached
216 private GraphVertex getHighestVersionFrom(GraphVertex v) {
217 Either<GraphVertex, JanusGraphOperationStatus> childVertexE = janusGraphDao
218 .getChildVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
219 GraphVertex highestVersionVertex = v;
221 while (childVertexE.isLeft()) {
222 highestVersionVertex = childVertexE.left().value();
223 childVertexE = janusGraphDao
224 .getChildVertex(highestVersionVertex, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
226 return highestVersionVertex;
229 private boolean isHighestVersion(GraphVertex v){
230 Boolean highest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
231 return highest != null && highest;
234 private List<String> handleParents(GraphVertex v, GraphVertex catalogRoot, GraphVertex archiveRoot, Action action) {
235 Either<GraphVertex, JanusGraphOperationStatus> parentVertexE = janusGraphDao
236 .getParentVertex(v, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
237 List<String> affectedCompIds = new ArrayList();
238 affectedCompIds.add(v.getUniqueId());
240 while (parentVertexE.isLeft()){
241 GraphVertex cv = parentVertexE.left().value();
242 affectedCompIds.add(cv.getUniqueId());
243 boolean isHighestVersion = isHighestVersion(cv);
244 if (isHighestVersion){
245 if (action == ARCHIVE) {
246 archiveEdges(catalogRoot, archiveRoot, cv);
248 restoreEdges(catalogRoot, archiveRoot, cv);
251 setPropertiesByAction(cv, action);
252 janusGraphDao.updateVertex(cv);
253 parentVertexE = janusGraphDao
254 .getParentVertex(cv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
256 return affectedCompIds;
259 private void archiveEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
260 janusGraphDao.deleteAllEdges(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT);
261 janusGraphDao.createEdge(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT, null);
262 setPropertiesByAction(v, ARCHIVE);
265 private void restoreEdges(GraphVertex catalogRoot, GraphVertex archiveRoot, GraphVertex v) {
266 janusGraphDao.deleteAllEdges(archiveRoot, v, EdgeLabelEnum.ARCHIVE_ELEMENT);
267 janusGraphDao.createEdge(catalogRoot, v, EdgeLabelEnum.CATALOG_ELEMENT, null);
268 setPropertiesByAction(v, RESTORE);
271 private void setPropertiesByAction(GraphVertex v, Action action) {
272 long now = System.currentTimeMillis();
274 boolean isArchived = action == ARCHIVE ? true : false;
275 v.addMetadataProperty(GraphPropertyEnum.IS_ARCHIVED, isArchived);
276 v.addMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME, now);
277 v.setJsonMetadataField(JsonPresentationFields.IS_ARCHIVED, isArchived);
278 v.setJsonMetadataField(JsonPresentationFields.ARCHIVE_TIME, now);
281 private ActionStatus onError(String action, String componentId, JanusGraphOperationStatus s) {
282 ActionStatus ret = ActionStatus.GENERAL_ERROR;
283 if (s == JanusGraphOperationStatus.NOT_FOUND){
284 ret = ActionStatus.RESOURCE_NOT_FOUND;
285 } else if (s == JanusGraphOperationStatus.ALREADY_LOCKED) {
286 ret = ActionStatus.COMPONENT_IN_USE;
288 String retCodeVal = ret.name();
289 log.error("error occurred when trying to {} {}. Return code is: {}", action, componentId, retCodeVal);