From 969a4e89e2363f76212623d9e563665804682fcf Mon Sep 17 00:00:00 2001 From: shrek2000 Date: Thu, 28 Mar 2019 16:29:17 +0200 Subject: Heal Vertex Data Enable healing of vertex information when reading it. Issue-ID: SDC-2213 Change-Id: I907beeb25bd231d9e05d3a5b8e070d6bdf9cb781 Signed-off-by: shrek2000 --- .../sdc/be/dao/config/DAOSpringConfig.java | 6 +- .../sdc/be/dao/config/TitanSpringConfig.java | 15 +- .../sdc/be/dao/graph/datatype/GraphNode.java | 33 +++- .../sdc/be/dao/impl/HealingPipelineDao.java | 172 +++++++++++++++++++++ .../sdc/be/dao/impl/heal/HealGraphDao.java | 6 + .../sdc/be/dao/impl/heal/HealNodeGraphDao.java | 35 +++++ .../sdc/be/dao/impl/heal/HealTitanGraphDao.java | 38 +++++ .../sdc/be/dao/impl/heal/HealVertexGraphDao.java | 39 +++++ .../sdc/be/dao/jsongraph/HealingTitanDao.java | 64 ++++++++ .../openecomp/sdc/be/dao/jsongraph/TitanDao.java | 2 +- .../jsongraph/heal/AbstractGraphVertexHeal.java | 24 +++ .../jsongraph/heal/AbstractTitanVertexHeal.java | 22 +++ .../openecomp/sdc/be/dao/jsongraph/heal/Heal.java | 27 ++++ .../sdc/be/dao/jsongraph/heal/HealConstants.java | 10 ++ .../sdc/be/dao/jsongraph/heal/HealVersion.java | 22 +++ .../be/dao/jsongraph/heal/HealVersionBuilder.java | 28 ++++ .../sdc/be/dao/jsongraph/heal/HealVersionImpl.java | 68 ++++++++ .../sdc/be/dao/titan/HealingTitanGenericDao.java | 128 +++++++++++++++ .../sdc/be/dao/titan/TitanGenericDao.java | 36 +++-- catalog-dao/src/main/resources/dao.properties | 16 ++ 20 files changed, 769 insertions(+), 22 deletions(-) create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/HealingPipelineDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealGraphDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealNodeGraphDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealTitanGraphDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealVertexGraphDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractGraphVertexHeal.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/Heal.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealConstants.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersion.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionBuilder.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionImpl.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java create mode 100644 catalog-dao/src/main/resources/dao.properties (limited to 'catalog-dao/src/main') diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/DAOSpringConfig.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/DAOSpringConfig.java index 99979bac0c..99acb3b62b 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/DAOSpringConfig.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/DAOSpringConfig.java @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.dao.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; @Configuration @Import({TitanSpringConfig.class}) @@ -33,10 +34,7 @@ import org.springframework.context.annotation.Import; "org.openecomp.sdc.be.dao.impl", "org.openecomp.sdc.be.resources.impl" }) +@PropertySource("classpath:dao.properties") public class DAOSpringConfig { - - - - } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java index 6360af8e04..34a860ddd2 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java @@ -2,7 +2,8 @@ package org.openecomp.sdc.be.dao.config; import org.openecomp.sdc.be.dao.DAOTitanStrategy; import org.openecomp.sdc.be.dao.TitanClientStrategy; -import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.titan.HealingTitanGenericDao; import org.openecomp.sdc.be.dao.titan.TitanGraphClient; import org.openecomp.sdc.be.dao.titan.transactions.SimpleTitanTransactionManager; import org.springframework.beans.factory.annotation.Qualifier; @@ -22,8 +23,8 @@ public class TitanSpringConfig { @Bean(name = "titan-generic-dao") @Primary - public TitanGenericDao titanGenericDao(@Qualifier("titan-client") TitanGraphClient titanGraphClient) { - return new TitanGenericDao(titanGraphClient); + public HealingTitanGenericDao titanGenericDao(@Qualifier("titan-client") TitanGraphClient titanGraphClient) { + return new HealingTitanGenericDao(titanGraphClient); } @Bean(name = "titan-client", initMethod = "createGraph") @@ -41,4 +42,12 @@ public class TitanSpringConfig { public PlatformTransactionManager txManager() { return new SimpleTitanTransactionManager(titanGraphClient(titanClientStrategy())); } + + @Bean(name = "healingPipelineDao") + public HealingPipelineDao healingPipeline(){ + HealingPipelineDao healingPipelineDao = new HealingPipelineDao(); + healingPipelineDao.setHealVersion(1); + healingPipelineDao.initHealVersion(); + return healingPipelineDao; + } } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphNode.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphNode.java index 35ab30c79a..3375719535 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphNode.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphNode.java @@ -21,13 +21,14 @@ package org.openecomp.sdc.be.dao.graph.datatype; import com.google.gson.Gson; +import java.util.List; +import java.util.Map; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealConstants; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; -import java.util.List; -import java.util.Map; - public abstract class GraphNode extends GraphElement { private static final Gson gson = new Gson(); @@ -61,15 +62,39 @@ public abstract class GraphNode extends GraphElement { } } + + + public abstract String getUniqueId(); + + public String getUniqueIdKey() { return GraphPropertiesDictionary.UNIQUE_ID.getProperty(); } - public abstract String getUniqueId(); + public String getHealingVersionKey() { + return GraphPropertyEnum.HEALING_VERSION.getProperty(); + } + + /** + * Must be overridden in implelemting classes + * @return current heal version. Default heal version if function not implemented. + */ + public Integer getHealingVersion(){ + return HealConstants.DEFAULT_HEAL_VERSION; + } + + /** + * Must be overriden in implementing classes + * @param version healing version number + */ + public void setHealingVersion(Integer version){ + + } @Override public String toString() { return "GraphNode [label=" + label + ", parent: " + super.toString() + "]"; } + } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/HealingPipelineDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/HealingPipelineDao.java new file mode 100644 index 0000000000..5b219b2371 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/HealingPipelineDao.java @@ -0,0 +1,172 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.dao.impl; + +import static java.util.stream.Collectors.joining; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.thinkaurelius.titan.core.TitanVertex; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElement; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.impl.heal.HealGraphDao; +import org.openecomp.sdc.be.dao.impl.heal.HealNodeGraphDao; +import org.openecomp.sdc.be.dao.impl.heal.HealTitanGraphDao; +import org.openecomp.sdc.be.dao.impl.heal.HealVertexGraphDao; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.heal.Heal; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersion; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersionBuilder; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component("healingPipelineDao") +public class HealingPipelineDao { + + private static Logger logger = Logger.getLogger(HealingPipelineDao.class.getName()); + + private HealVersion currentHealVersion; + + @Value("${current.heal.version}") + private Integer healVersion; + + private ImmutableListMultimap healingPipeline; + + private HealGraphDao healNodeGraphDao; + private HealGraphDao healVertexGraphDao; + private HealGraphDao healTitanVertexGraphDao; + + public HealingPipelineDao() { + healingPipeline = ImmutableListMultimap.of(); + checkValidation(healingPipeline); + } + + @PostConstruct + public void initHealVersion() { + currentHealVersion = HealVersionBuilder.build(healVersion); + } + + @PostConstruct + public void initGraphHealers() { + healNodeGraphDao = new HealNodeGraphDao(this); + healVertexGraphDao = new HealVertexGraphDao(this); + healTitanVertexGraphDao = new HealTitanGraphDao(this); + } + + + private HealGraphDao supplyHealer(Object graphNode) { + if (graphNode instanceof GraphVertex) { + return healVertexGraphDao; + } + if (graphNode instanceof GraphElement) { + return healNodeGraphDao; + } + if (graphNode instanceof TitanVertex) { + return healTitanVertexGraphDao; + } + + return null; + } + + + public ImmutableListMultimap getHealingPipeline() { + return healingPipeline; + } + + public boolean shouldHeal(HealVersion healerVersion, HealVersion vertexVersion) { + Objects.requireNonNull(healerVersion); + Objects.requireNonNull(vertexVersion); + if (healerVersion.compareTo(currentHealVersion) >= 0) { + return false; + } + return healerVersion.compareTo(vertexVersion) >= 0; + } + + public void setHealVersion(Integer healVersion) { + this.healVersion = healVersion; + } + + + public ImmutableList getHealersForVertex(String edgeLabelEnum, HealVersion vertexVersion) { + final ImmutableList vertexHeals = getHealingPipeline().get(edgeLabelEnum); + List list = new ArrayList<>(); + for (Heal heal : vertexHeals) { + if (shouldHeal(heal.fromVersion(), vertexVersion)) { + list.add(heal); + } + } + return ImmutableList.copyOf(list); + } + + + public void setHealingPipeline(ImmutableListMultimap healingPipeline) { + checkValidation(healingPipeline); + this.healingPipeline = healingPipeline; + } + + + public void setHealingVersion(final GraphVertex graphVertex) { + graphVertex.addMetadataProperty(GraphPropertyEnum.HEALING_VERSION, currentHealVersion.getVersion()); + } + + public void setHealingVersion(TitanVertex graphVertex) { + graphVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty(), currentHealVersion.getVersion()); + } + + public void setHealingVersion(GraphNode graphNode) { + graphNode.setHealingVersion(currentHealVersion.getVersion()); + } + + public HealVersion getCurrentHealVersion() { + return currentHealVersion; + } + + public Optional performGraphReadHealing(Object graphNode, Object edgeLabel) { + HealGraphDao healGraphDao = supplyHealer(graphNode); + if (healGraphDao == null) { + logger.error("Unexpected graph node : {}", graphNode.getClass().getCanonicalName()); + return Optional.empty(); + } + return Optional.of(healGraphDao.performGraphReadHealing(graphNode, edgeLabel)); + } + + /** + * prevent duplicated healing version for same edge label. + */ + private void checkValidation(ImmutableListMultimap listMultimap) { + listMultimap.keySet().forEach(key -> this.validNoDuplicates(key, listMultimap.get(key))); + } + + private void validNoDuplicates(String key, List heals) { + Set duplicatedVersionSet = new HashSet<>(); + Set duplicatedNumbersSet = heals.stream().map(heal -> ((HealVersion) heal.fromVersion()).getVersion()).filter(n -> !duplicatedVersionSet.add(n)).collect(Collectors.toSet()); + if (!duplicatedNumbersSet.isEmpty()) { + throw new IllegalStateException(String.format("Edge label %s , contains multiple healing with same version %s", key, duplicatedNumbersSet.stream().map(Object::toString).collect(joining(" , ", "[ ", " ]")))); + } + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealGraphDao.java new file mode 100644 index 0000000000..b8e5a3c041 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealGraphDao.java @@ -0,0 +1,6 @@ +package org.openecomp.sdc.be.dao.impl.heal; + +@FunctionalInterface +public interface HealGraphDao { + G performGraphReadHealing(G childVertex, L edgeLabelEnum); +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealNodeGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealNodeGraphDao.java new file mode 100644 index 0000000000..2fc5c8fc5d --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealNodeGraphDao.java @@ -0,0 +1,35 @@ +package org.openecomp.sdc.be.dao.impl.heal; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.jsongraph.heal.Heal; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersion; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersionBuilder; + +public class HealNodeGraphDao implements HealGraphDao { + + private HealingPipelineDao healingPipelineDao; + + + public HealNodeGraphDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } + + @Override + public GraphNode performGraphReadHealing(GraphNode childVertex, GraphEdge graphEdge) { + Integer healingVersionInt = childVertex.getHealingVersion(); + HealVersion healingVersion = HealVersionBuilder.build(healingVersionInt); + healingPipelineDao.getHealersForVertex(graphEdge.getEdgeType().getProperty(), healingVersion).forEach(heal -> healTitanVertex(childVertex, heal)); + childVertex.setHealingVersion(healingPipelineDao.getCurrentHealVersion().getVersion()); + return childVertex; + } + + private GraphNode healTitanVertex(GraphNode childVertex, Heal heal) { + heal.healData(childVertex); + final HealVersion healVersion = heal.fromVersion(); + HealVersion newerVersion = HealVersionBuilder.build(healVersion.getVersion() + 1); + childVertex.setHealingVersion(newerVersion.getVersion()); + return childVertex; + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealTitanGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealTitanGraphDao.java new file mode 100644 index 0000000000..1e33c61b9f --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealTitanGraphDao.java @@ -0,0 +1,38 @@ +package org.openecomp.sdc.be.dao.impl.heal; + +import com.thinkaurelius.titan.core.TitanVertex; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.jsongraph.heal.Heal; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealConstants; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersion; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersionBuilder; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; + +public class HealTitanGraphDao implements HealGraphDao { + + private HealingPipelineDao healingPipelineDao; + + public HealTitanGraphDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } + + @Override + public TitanVertex performGraphReadHealing(TitanVertex childVertex, GraphEdgeLabels graphEdgeLabels) { + final Integer healingVersionInt = (Integer) childVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty()).orElse(HealConstants.DEFAULT_HEAL_VERSION); + HealVersion healingVersion = HealVersionBuilder.build(healingVersionInt); + healingPipelineDao.getHealersForVertex(graphEdgeLabels.name(), healingVersion).forEach(heal -> healGraphVertex(childVertex, heal)); + childVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty(), healingPipelineDao.getCurrentHealVersion().getVersion()); + return childVertex; + } + + + private TitanVertex healGraphVertex(TitanVertex childVertex, Heal heal) { + heal.healData(childVertex); + final HealVersion healVersion = heal.fromVersion(); + HealVersion newerVersion = HealVersionBuilder.build(healVersion.getVersion() + 1); + childVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty(), newerVersion); + heal.healData(childVertex); + return childVertex; + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealVertexGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealVertexGraphDao.java new file mode 100644 index 0000000000..b8eb670176 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealVertexGraphDao.java @@ -0,0 +1,39 @@ +package org.openecomp.sdc.be.dao.impl.heal; + +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.heal.Heal; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealConstants; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersion; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersionBuilder; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; + +public class HealVertexGraphDao implements HealGraphDao { + + private HealingPipelineDao healingPipelineDao; + + public HealVertexGraphDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } + + @Override + public GraphVertex performGraphReadHealing( GraphVertex childVertex, EdgeLabelEnum edgeLabelEnum) { + final Integer healingVersionInt = (Integer) childVertex.getMetadataProperties() + .getOrDefault(GraphPropertyEnum.HEALING_VERSION, HealConstants.DEFAULT_HEAL_VERSION); + HealVersion healingVersion = HealVersionBuilder.build(healingVersionInt); + healingPipelineDao.getHealersForVertex(edgeLabelEnum.name(), healingVersion).forEach(heal -> healGraphVertex(childVertex, heal)); + childVertex.addMetadataProperty(GraphPropertyEnum.HEALING_VERSION, healingPipelineDao.getCurrentHealVersion().getVersion()); + return childVertex; + } + + + private GraphVertex healGraphVertex(GraphVertex childVertex, Heal heal) { + heal.healData(childVertex); + final HealVersion healVersion = heal.fromVersion(); + HealVersion newerVersion = HealVersionBuilder.build(healVersion.getVersion() + 1); + childVertex.addMetadataProperty(GraphPropertyEnum.HEALING_VERSION, newerVersion); + heal.healData(childVertex); + return childVertex; + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java new file mode 100644 index 0000000000..fb6b9d8fa3 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java @@ -0,0 +1,64 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.dao.jsongraph; + +import fj.data.Either; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.titan.TitanGraphClient; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("titan-dao") +public class HealingTitanDao extends TitanDao { + + + @Autowired + private HealingPipelineDao healingPipelineDao; + + + public HealingTitanDao(TitanGraphClient titanClient) { + super(titanClient); + } + + @Override + public Either, TitanOperationStatus> getChildrenVertecies(GraphVertex parentVertex, + EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, TitanOperationStatus> childrenVertecies = + super.getChildrenVertecies(parentVertex, edgeLabel, parseFlag); + return Either.iif(childrenVertecies.isRight(), () -> childrenVertecies.right().value(), + () -> childrenVertecies.left().value().stream() + .map(graphVertex -> transformVertex(graphVertex, edgeLabel)) + .collect(Collectors.toList())); + } + + private GraphVertex transformVertex(GraphVertex graphVertex, EdgeLabelEnum edgeLabelEnum) { + Optional optional = healingPipelineDao.performGraphReadHealing(graphVertex, edgeLabelEnum); + return optional.orElse(graphVertex); + } + + + public void setHealingPipelineDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java index e01cddceb0..a31900acce 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java @@ -48,7 +48,7 @@ import java.util.Map.Entry; import static org.apache.commons.collections.CollectionUtils.isEmpty; -@Component("titan-dao") + public class TitanDao { TitanGraphClient titanClient; diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractGraphVertexHeal.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractGraphVertexHeal.java new file mode 100644 index 0000000000..9be730ca95 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractGraphVertexHeal.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdc.be.dao.jsongraph.heal; + +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.common.log.wrappers.Logger; + +public abstract class AbstractGraphVertexHeal implements Heal { + + protected Logger logger = Logger.getLogger(AbstractGraphVertexHeal.class); +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java new file mode 100644 index 0000000000..e01ddab989 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdc.be.dao.jsongraph.heal; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; + +public abstract class AbstractTitanVertexHeal implements Heal { + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/Heal.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/Heal.java new file mode 100644 index 0000000000..6c60772e8a --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/Heal.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdc.be.dao.jsongraph.heal; + +public interface Heal { + + + HealVersion fromVersion(); + + void healData(V parentV); + + + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealConstants.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealConstants.java new file mode 100644 index 0000000000..ce1b24ab36 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealConstants.java @@ -0,0 +1,10 @@ +package org.openecomp.sdc.be.dao.jsongraph.heal; + +public class HealConstants { + + public static final Integer DEFAULT_HEAL_VERSION = 0; + private HealConstants() { + } + + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersion.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersion.java new file mode 100644 index 0000000000..55d3f43c79 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersion.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.dao.jsongraph.heal; + +public interface HealVersion extends Comparable { + + T getVersion(); +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionBuilder.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionBuilder.java new file mode 100644 index 0000000000..3a7b0645c1 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionBuilder.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.dao.jsongraph.heal; + +public class HealVersionBuilder { + + private HealVersionBuilder() { + } + + public static HealVersion build(Integer version) { + return new HealVersionImpl(version); + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionImpl.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionImpl.java new file mode 100644 index 0000000000..4ce28debc1 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/HealVersionImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.dao.jsongraph.heal; + +import com.google.common.base.MoreObjects; +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +class HealVersionImpl implements HealVersion { + + private final T version; + + public HealVersionImpl(T version) { + Objects.requireNonNull(version, "Version cannot be null"); + this.version = version; + } + + public T getVersion() { + return version; + } + + + @Override + public int compareTo(HealVersion o) { + return this.version.compareTo( o.getVersion()); + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof HealVersionImpl)) { + return false; + } + + HealVersionImpl that = (HealVersionImpl) o; + + return new EqualsBuilder().append(getVersion(), that.getVersion()).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(getVersion()).toHashCode(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("version", version).toString(); + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java new file mode 100644 index 0000000000..37546a5c2a --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java @@ -0,0 +1,128 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openecomp.sdc.be.dao.titan; + +import com.thinkaurelius.titan.core.TitanVertex; +import fj.data.Either; +import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.jsongraph.heal.Heal; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealConstants; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersion; +import org.openecomp.sdc.be.dao.jsongraph.heal.HealVersionBuilder; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("titan-generic-dao") +public class HealingTitanGenericDao extends TitanGenericDao { + + @Autowired + private HealingPipelineDao healingPipelineDao; + + public HealingTitanGenericDao(TitanGraphClient titanClient) { + super(titanClient); + } + + @Override + public ImmutablePair getChildVertex(TitanVertex childVertex, GraphEdgeLabels edgeType) { + ImmutablePair childVertexEdgeImmutablePair = super.getChildVertex(childVertex, edgeType); + final TitanVertex graphVertex = childVertexEdgeImmutablePair.left; + healingPipelineDao.performGraphReadHealing(graphVertex, edgeType); + healingPipelineDao.setHealingVersion(graphVertex); + return childVertexEdgeImmutablePair; + } + + @Override + public Either>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, boolean withEdges) { + Either>, TitanOperationStatus> either = super.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, withEdges); + if (either.isRight()) { + return either; + } + List> list = either.left().value(); + list.forEach(this::transformPair); + return either; + } + + @Override + public Either, TitanOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + Either, TitanOperationStatus> eitherChild = super.getChild(key, uniqueId, edgeType, nodeTypeEnum, clazz); + if (eitherChild.isRight()) { + return eitherChild; + } + ImmutablePair pair = eitherChild.left().value(); + GraphNode graphNode = pair.left; + GraphEdge graphEdge = pair.right; + healingPipelineDao.performGraphReadHealing(graphNode, graphEdge); + healingPipelineDao.setHealingVersion(graphNode); + return eitherChild; + } + + private void transformPair(ImmutablePair either) { + GraphEdge edgeType = either.right; + GraphNode childVertex = either.left; + Integer healingVersioInt = childVertex.getHealingVersion(); + HealVersionBuilder.build(healingVersioInt); + healingPipelineDao.performGraphReadHealing(childVertex, edgeType); + healingPipelineDao.setHealingVersion(childVertex); + } + + @Override + public Either>, TitanOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) { + Either>, TitanOperationStatus> either = super.getChildrenVertecies(key, uniqueId, edgeType); + if (either.isRight()) { + return either; + } + List> list = either.left().value(); + list.forEach(this::transformVertexPair); + return either; + } + + private void transformVertexPair(ImmutablePair either) { + String edgeType = either.right.label(); + TitanVertex childVertex = either.left; + VertexProperty healingVersionProperty = childVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty()); + Integer healingVersioInt = healingVersionProperty.orElse(HealConstants.DEFAULT_HEAL_VERSION); + HealVersionBuilder.build(healingVersioInt); + healingPipelineDao.performGraphReadHealing(childVertex, edgeType); + healingPipelineDao.setHealingVersion(childVertex); + } + + @Override + public Either updateNode(GraphNode node, Class clazz) { + healingPipelineDao.setHealingVersion(node); + return super.updateNode(node, clazz); + } + + @Override + public TitanOperationStatus updateVertex(GraphNode node, Vertex vertex) { + healingPipelineDao.setHealingVersion(node); + return super.updateVertex(node, vertex); + } + + + public void setHealingPipelineDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java index 3c502ffccb..2123910650 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java @@ -20,28 +20,44 @@ package org.openecomp.sdc.be.dao.titan; -import com.thinkaurelius.titan.core.*; +import com.thinkaurelius.titan.core.PropertyKey; +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanGraphQuery; +import com.thinkaurelius.titan.core.TitanVertex; +import com.thinkaurelius.titan.core.TitanVertexQuery; import com.thinkaurelius.titan.graphdb.query.TitanPredicate; import fj.data.Either; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutableTriple; -import org.apache.tinkerpop.gremlin.structure.*; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.graph.GraphElementFactory; -import org.openecomp.sdc.be.dao.graph.datatype.*; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.resources.data.GraphNodeLock; import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Component; +import org.springframework.beans.factory.annotation.Qualifier; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; -@Component("titan-generic-dao") public class TitanGenericDao { private static final String FAILED_TO_RETRIEVE_GRAPH_STATUS_IS = "Failed to retrieve graph. status is {}"; @@ -51,7 +67,7 @@ public class TitanGenericDao { private static Logger log = Logger.getLogger(TitanGenericDao.class.getName()); private static final String LOCK_NODE_PREFIX = "lock_"; - public TitanGenericDao(TitanGraphClient titanClient) { + public TitanGenericDao(@Qualifier("titan-client") TitanGraphClient titanClient) { this.titanClient = titanClient; log.info("** TitanGenericDao created"); } diff --git a/catalog-dao/src/main/resources/dao.properties b/catalog-dao/src/main/resources/dao.properties new file mode 100644 index 0000000000..5306906bd1 --- /dev/null +++ b/catalog-dao/src/main/resources/dao.properties @@ -0,0 +1,16 @@ +# +# Copyright ? 2016-2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +current.heal.version = 0 \ No newline at end of file -- cgit 1.2.3-korg