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;
23 import com.thinkaurelius.titan.core.PropertyKey;
24 import com.thinkaurelius.titan.core.TitanGraph;
25 import com.thinkaurelius.titan.core.TitanVertex;
26 import com.thinkaurelius.titan.core.schema.TitanManagement;
27 import fj.data.Either;
28 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
29 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
30 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.stereotype.Component;
37 import java.util.Optional;
39 @Component("migrationUtils")
40 public class MigrationOperationUtils {
42 private static Logger log = LoggerFactory.getLogger(MigrationOperationUtils.class);
45 private TitanGenericDao titanGenericDao;
48 * rename a set or property keys
50 * @param propertyKeys a mapping between the old property key name and the property key name to replace it with
52 * @return true if rename ended successfully or false otherwise
54 public boolean renamePropertyKeys(Map<String, String> propertyKeys) {
55 Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph();
56 return graph.either((titanGraph) -> renamePropertyKeys(titanGraph, propertyKeys),
57 (titanOperationStatus) -> operationFailed(MigrationMsg.FAILED_TO_RETRIEVE_GRAPH.getMessage(titanOperationStatus.name())));
60 private boolean renamePropertyKeys(TitanGraph titanGraph, Map<String, String> propertyKeys) {
62 for (Map.Entry<String, String> propertyKeyEntry : propertyKeys.entrySet()) {
63 boolean renameSucceeded = renamePropertyKey(titanGraph, propertyKeyEntry);
64 if (!renameSucceeded) {
69 } catch (RuntimeException e) {
70 log.error(e.getMessage(), e);
75 private Boolean renamePropertyKey(TitanGraph titanGraph, Map.Entry<String, String> propertyKeyEntry) {
76 String renameFromKey = propertyKeyEntry.getKey();
77 String renameToKey = propertyKeyEntry.getValue();
78 log.info(String.format("renaming property key %s to %s", renameFromKey, renameToKey));
79 return renameProperty(titanGraph, renameFromKey, renameToKey);
82 private Boolean renameProperty(TitanGraph titanGraph, String renameFromKey, String renameToKey) {
83 if (titanGraph.containsPropertyKey(renameFromKey) && titanGraph.containsPropertyKey(renameToKey)) {//new property already exist, we cant rename to it we need to add new and remove old on every vertices which has the old one.
84 return renamePropertyOnEachVertex(titanGraph, renameFromKey, renameToKey);
86 return renamePropertyOnGraphLevel(titanGraph, renameFromKey, renameToKey);
89 private Boolean renamePropertyOnGraphLevel(TitanGraph titanGraph, String renameFromKey, String renameToKey) {
90 TitanManagement titanManagement = titanGraph.openManagement();
91 return Optional.ofNullable(titanManagement.getPropertyKey(renameFromKey))
92 .map(propertyKey -> renamePropertyOnGraph(titanManagement, propertyKey, renameToKey))
93 .orElseGet(() -> {log.info(MigrationMsg.PROPERTY_KEY_NOT_EXIST.getMessage(renameFromKey)); return true;}) ;//if property key not exist rename is considered to be successful
96 private boolean renamePropertyOnEachVertex(TitanGraph graph, String oldKey, String newKey) {
97 addNewPropertyKeyOnVertices(graph, oldKey, newKey);
98 removeOldPropertyKeyFromGraph(graph, oldKey);
103 private void removeOldPropertyKeyFromGraph(TitanGraph graph, String oldKey) {
104 graph.getPropertyKey(oldKey).remove();
107 private void addNewPropertyKeyOnVertices(TitanGraph graph, String oldKey, String newKey) {
108 graph.query().has(oldKey).vertices().forEach(titanVertex -> {
109 copyOldKeyValueAndDropKey(oldKey, newKey, (TitanVertex) titanVertex);
113 private void copyOldKeyValueAndDropKey(String oldKey, String newKey, TitanVertex titanVertex) {
114 VertexProperty<Object> oldProperty = titanVertex.property(oldKey);
115 Object oldKeyValue = oldProperty.value();
117 titanVertex.property(newKey, oldKeyValue);
118 oldProperty.remove();
121 private boolean renamePropertyOnGraph(TitanManagement titanManagement, PropertyKey fromPropertyKey, String toKey) {
123 titanManagement.changeName(fromPropertyKey, toKey);
124 titanManagement.commit();
126 } catch (RuntimeException e) {
127 log.error(MigrationMsg.RENAME_KEY_PROPERTY_FAILED.getMessage(fromPropertyKey.name()), e.getMessage());
128 titanManagement.rollback();
133 private boolean operationFailed(String errorMessage) {
134 log.error(errorMessage);