2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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.migration.v1707.jsonmodel;
23 import com.thinkaurelius.titan.core.TitanVertex;
24 import fj.data.Either;
25 import org.apache.tinkerpop.gremlin.structure.Direction;
26 import org.apache.tinkerpop.gremlin.structure.Edge;
27 import org.apache.tinkerpop.gremlin.structure.Property;
28 import org.apache.tinkerpop.gremlin.structure.Vertex;
29 import org.openecomp.sdc.asdctool.impl.migration.MigrationMsg;
30 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
31 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
32 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
33 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
34 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
35 import org.openecomp.sdc.be.resources.data.UserData;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import javax.annotation.Resource;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.stream.Collectors;
44 import static fj.data.List.list;
45 import static org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils.handleError;
47 public class UserStatesMigration extends JsonModelMigration<Edge> {
49 private static final String MIGRATING_USER_ID = "jh0003";
50 private static final int OUT_VERTEX_INDEX = 0;
51 private static final int IN_VERTEX_INDEX = 1;
52 private static Logger LOGGER = LoggerFactory.getLogger(UserStatesMigration.class);
54 @Resource(name = "titan-generic-dao")
55 private TitanGenericDao genericDao;
57 @Resource(name = "titan-generic-dao-migration")
58 private TitanGenericDao genericDaoMigration;
61 public String description() {
62 return "migrate user states";
67 public boolean migrate() {
68 // return removeMigratingUserStates() && super.migrate();
69 return super.migrate();
73 Either<List<Edge>, TitanOperationStatus> getElementsToMigrate() {
74 LOGGER.debug("fetching user states edges from old graph");
75 return genericDao.getAll(NodeTypeEnum.User, UserData.class)
76 .left().bind(this::getEdgesForUsers);
80 Either<Edge, TitanOperationStatus> getElementFromNewGraph(Edge edge) {
81 LOGGER.debug("finding user state edge in new graph");
82 Vertex outVertex = edge.outVertex();
83 String outVertexUIDKey = getVertexUniqueId(outVertex);
84 String outVertexUIDValue = outVertex.property(outVertexUIDKey).value().toString();
86 Vertex inVertex = edge.inVertex();
87 String inVertexUIDKey = getVertexUniqueId(inVertex);
88 String inVertexUIDValue = inVertex.property(inVertexUIDKey).value().toString();
90 return genericDaoMigration.getEdgeByVerticies(outVertexUIDKey, outVertexUIDValue, inVertexUIDKey, inVertexUIDValue, edge.label());
94 boolean save(Edge userState) {
95 Either<InOutVertices, TitanOperationStatus> titanVertices = findEdgeInOutVerticesInNewGraph(userState);
96 return titanVertices.either(inOutVertices -> saveUserState(inOutVertices, userState),
97 err -> handleError(String.format("could not find user edge %s in vertx. error: %s", userState.label(), err.name())));
100 private boolean saveUserState(InOutVertices inOutVertices, Edge userState) {
101 return genericDaoMigration.copyEdge(inOutVertices.getOutVertex(), inOutVertices.getInVertex(), userState)
102 .either(edge -> true,
103 err -> handleError(String.format("failed to save user state edge %s. reason: %s", userState.label(), err.name())));
107 TitanOperationStatus getNotFoundErrorStatus() {
108 return TitanOperationStatus.NOT_FOUND;
111 // private boolean removeMigratingUserStates() {
112 // Either<UserData, TitanOperationStatus> migratingUser = genericDaoMigration.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), MIGRATING_USER_ID, UserData.class);
113 // return migratingUser.either(user -> deleteAllEdges(user, Direction.OUT),
114 // errorStatus -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_MIGRATION_USER.getMessage(MIGRATING_USER_ID, errorStatus.name())));
117 private Either<List<Edge>, TitanOperationStatus> getEdgesForUsers(List<UserData> users) {
118 List<Edge> edges = new ArrayList<>();
119 for (UserData user : users) {
120 Either<List<Edge>, TitanOperationStatus> edgesForNode = genericDao.getEdgesForNode(user, Direction.OUT);
121 if (edgesForNode.isRight()) {
122 TitanOperationStatus errorStatus = edgesForNode.right().value();
123 LOGGER.error(MigrationMsg.FAILED_TO_RETRIEVE_USER_STATES.getMessage(user.getEmail(), errorStatus.name()));
124 return Either.right(errorStatus);
126 edges.addAll(edgesForNode.left().value());
128 return Either.left(ignoreProductEdges(edges));
131 private List<Edge> ignoreProductEdges(List<Edge> edges) {
132 return edges.stream().filter(edge -> !isInEdgeOfProductType(edge.inVertex())).collect(Collectors.toList());
135 private boolean isInEdgeOfProductType(Vertex inVertex) {
136 Property<Object> nodeLabelProperty = inVertex.property(GraphPropertiesDictionary.LABEL.getProperty());
137 return nodeLabelProperty != null && nodeLabelProperty.value().equals(NodeTypeEnum.Product.getName());
140 private String getVertexUniqueId(Vertex vertex) {
141 String nodeLabel = vertex.property(GraphPropertiesDictionary.LABEL.getProperty()).value().toString();
142 return UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(nodeLabel));
145 private Either<InOutVertices, TitanOperationStatus> findEdgeInOutVerticesInNewGraph(Edge userEdge) {
146 Either<TitanVertex, TitanOperationStatus> outVertex = getMigratedVertexByOldVertex(userEdge.outVertex());
147 Either<TitanVertex, TitanOperationStatus> inVertex = getMigratedVertexByOldVertex(userEdge.inVertex());
148 return Either.sequenceLeft(list(outVertex, inVertex)).left().map(InOutVertices::new);
151 private Either<TitanVertex, TitanOperationStatus> getMigratedVertexByOldVertex(Vertex vertex) {
152 String vertexUniqueId = getVertexUniqueId(vertex);
153 LOGGER.debug(String.format("fetching vertex %s from new graph", vertexUniqueId));
154 return genericDaoMigration.getVertexByProperty(vertexUniqueId, vertex.property(vertexUniqueId).value())
155 .right().map(err -> handleError(err, String.format("could not find vertex %s in new graph.", vertexUniqueId))) ;
158 // private boolean deleteAllEdges(UserData userData, Direction direction) {
159 // Either<List<Edge>, TitanOperationStatus> edgesForNode = genericDaoMigration.getEdgesForNode(userData, direction);
160 // if (edgesForNode.isRight()) {
161 // LOGGER.error(MigrationMsg.FAILED_TO_RETRIEVE_MIGRATION_USER_STATES.getMessage(MIGRATING_USER_ID, edgesForNode.right().value().name()));
164 // edgesForNode.left().value().forEach(Edge::remove);
168 private class InOutVertices {
169 private TitanVertex outVertex;
170 private TitanVertex inVertex;
172 InOutVertices(fj.data.List<TitanVertex> inOutVertices) {
173 outVertex = inOutVertices.index(OUT_VERTEX_INDEX);
174 inVertex = inOutVertices.index(IN_VERTEX_INDEX);
177 TitanVertex getOutVertex() {
181 TitanVertex getInVertex() {