3f622739315fa898e01a0e922f6e865c85e5974a
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
22
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;
38
39 import javax.annotation.Resource;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.stream.Collectors;
43
44 import static fj.data.List.list;
45 import static org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils.handleError;
46
47 public class UserStatesMigration extends JsonModelMigration<Edge> {
48
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);
53
54     @Resource(name = "titan-generic-dao")
55     private TitanGenericDao genericDao;
56
57     @Resource(name = "titan-generic-dao-migration")
58     private TitanGenericDao genericDaoMigration;
59
60     @Override
61     public String description() {
62         return "migrate user states";
63     }
64
65
66     @Override
67     public boolean migrate() {
68 //        return removeMigratingUserStates() && super.migrate();
69         return super.migrate();
70     }
71
72     @Override
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);
77     }
78
79     @Override
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();
85
86         Vertex inVertex = edge.inVertex();
87         String inVertexUIDKey = getVertexUniqueId(inVertex);
88         String inVertexUIDValue = inVertex.property(inVertexUIDKey).value().toString();
89
90         return genericDaoMigration.getEdgeByVerticies(outVertexUIDKey, outVertexUIDValue, inVertexUIDKey, inVertexUIDValue, edge.label());
91     }
92
93     @Override
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())));
98     }
99
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())));
104     }
105
106     @Override
107     TitanOperationStatus getNotFoundErrorStatus() {
108         return TitanOperationStatus.NOT_FOUND;
109     }
110
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())));
115 //    }
116
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);
125             }
126             edges.addAll(edgesForNode.left().value());
127         }
128         return Either.left(ignoreProductEdges(edges));
129     }
130
131     private List<Edge> ignoreProductEdges(List<Edge> edges) {
132         return edges.stream().filter(edge -> !isInEdgeOfProductType(edge.inVertex())).collect(Collectors.toList());
133     }
134
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());
138     }
139
140     private String getVertexUniqueId(Vertex vertex) {
141         String nodeLabel = vertex.property(GraphPropertiesDictionary.LABEL.getProperty()).value().toString();
142         return UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(nodeLabel));
143     }
144
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);
149     }
150
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)))  ;
156     }
157
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()));
162 //            return false;
163 //        }
164 //        edgesForNode.left().value().forEach(Edge::remove);
165 //        return true;
166 //    }
167
168     private class InOutVertices {
169         private TitanVertex outVertex;
170         private TitanVertex inVertex;
171
172         InOutVertices(fj.data.List<TitanVertex> inOutVertices) {
173             outVertex = inOutVertices.index(OUT_VERTEX_INDEX);
174             inVertex = inOutVertices.index(IN_VERTEX_INDEX);
175         }
176
177         TitanVertex getOutVertex() {
178             return outVertex;
179         }
180
181         TitanVertex getInVertex() {
182             return inVertex;
183         }
184
185     }
186
187 }