From 2623c8402a57e2035db69a9d92d2851050916801 Mon Sep 17 00:00:00 2001 From: shrikantawachar Date: Mon, 20 May 2019 12:11:54 +0530 Subject: Upgrade SDC from Titan to Janus Graph Upgrade SDC from Titan to Janus Graph Change-Id: I67fb8b8e60cc6751697bc5ff2f06754c92803786 Issue-ID: SDC-2296 Signed-off-by: shrikantawachar --- .../sdc/be/dao/DAOJanusGraphStrategy.java | 32 + .../org/openecomp/sdc/be/dao/DAOTitanStrategy.java | 32 - .../sdc/be/dao/JanusGraphClientStrategy.java | 27 + .../openecomp/sdc/be/dao/TitanClientStrategy.java | 27 - .../be/dao/cassandra/schema/SdcSchemaBuilder.java | 2 +- .../sdc/be/dao/config/DAOSpringConfig.java | 2 +- .../sdc/be/dao/config/JanusGraphSpringConfig.java | 54 + .../sdc/be/dao/config/TitanSpringConfig.java | 53 - .../sdc/be/dao/impl/HealingPipelineDao.java | 14 +- .../sdc/be/dao/impl/heal/HealJanusGraphDao.java | 38 + .../sdc/be/dao/impl/heal/HealNodeGraphDao.java | 4 +- .../sdc/be/dao/impl/heal/HealTitanGraphDao.java | 38 - .../janusgraph/HealingJanusGraphGenericDao.java | 126 ++ .../sdc/be/dao/janusgraph/JanusGraphClient.java | 412 +++++ .../be/dao/janusgraph/JanusGraphGenericDao.java | 1770 ++++++++++++++++++++ .../dao/janusgraph/JanusGraphOperationStatus.java | 26 + .../sdc/be/dao/janusgraph/JanusGraphUtils.java | 27 + .../openecomp/sdc/be/dao/janusgraph/QueryType.java | 28 + .../SimpleJanusGraphTransactionManager.java | 70 + .../sdc/be/dao/jsongraph/GraphVertex.java | 8 +- .../sdc/be/dao/jsongraph/HealingJanusGraphDao.java | 64 + .../sdc/be/dao/jsongraph/HealingTitanDao.java | 64 - .../sdc/be/dao/jsongraph/JanusGraphDao.java | 1077 ++++++++++++ .../openecomp/sdc/be/dao/jsongraph/TitanDao.java | 1078 ------------ .../heal/AbstractJanusGraphVertexHeal.java | 22 + .../jsongraph/heal/AbstractTitanVertexHeal.java | 22 - .../sdc/be/dao/titan/HealingTitanGenericDao.java | 128 -- .../org/openecomp/sdc/be/dao/titan/QueryType.java | 28 - .../sdc/be/dao/titan/TitanGenericDao.java | 1769 ------------------- .../sdc/be/dao/titan/TitanGraphClient.java | 408 ----- .../sdc/be/dao/titan/TitanOperationStatus.java | 26 - .../org/openecomp/sdc/be/dao/titan/TitanUtils.java | 27 - .../SimpleTitanTransactionManager.java | 70 - .../data/auditing/AuditingTypesConstants.java | 2 +- 34 files changed, 3789 insertions(+), 3786 deletions(-) create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOJanusGraphStrategy.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOTitanStrategy.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/JanusGraphClientStrategy.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/TitanClientStrategy.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/JanusGraphSpringConfig.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealJanusGraphDao.java delete 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/janusgraph/HealingJanusGraphGenericDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphGenericDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphOperationStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphUtils.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/QueryType.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/transactions/SimpleJanusGraphTransactionManager.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingJanusGraphDao.java delete 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/JanusGraphDao.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractJanusGraphVertexHeal.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/QueryType.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGraphClient.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanOperationStatus.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanUtils.java delete mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/transactions/SimpleTitanTransactionManager.java (limited to 'catalog-dao/src/main/java') diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOJanusGraphStrategy.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOJanusGraphStrategy.java new file mode 100644 index 0000000000..1a96ebf87b --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOJanusGraphStrategy.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao; + +import org.openecomp.sdc.be.config.ConfigurationManager; + +public class DAOJanusGraphStrategy implements JanusGraphClientStrategy { + + @Override + public String getConfigFile() { + return ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphCfgFile(); + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOTitanStrategy.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOTitanStrategy.java deleted file mode 100644 index 2452245616..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/DAOTitanStrategy.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao; - -import org.openecomp.sdc.be.config.ConfigurationManager; - -public class DAOTitanStrategy implements TitanClientStrategy { - - @Override - public String getConfigFile() { - return ConfigurationManager.getConfigurationManager().getConfiguration().getTitanCfgFile(); - } - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/JanusGraphClientStrategy.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/JanusGraphClientStrategy.java new file mode 100644 index 0000000000..14e12e9b04 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/JanusGraphClientStrategy.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao; + +public interface JanusGraphClientStrategy { + + String getConfigFile(); + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/TitanClientStrategy.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/TitanClientStrategy.java deleted file mode 100644 index 36aaec8684..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/TitanClientStrategy.java +++ /dev/null @@ -1,27 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao; - -public interface TitanClientStrategy { - - String getConfigFile(); - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/SdcSchemaBuilder.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/SdcSchemaBuilder.java index 5af12a8af1..53d71fe3cf 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/SdcSchemaBuilder.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/SdcSchemaBuilder.java @@ -120,7 +120,7 @@ public class SdcSchemaBuilder { Map>> cassndraMetadata = parseKeyspaceMetadata(keyspacesMetadateFromCassandra); log.info("Cassandra Metadata: {}" ,cassndraMetadata); cassndraMetadata.forEach((k, v) -> { - if (AuditingTypesConstants.TITAN_KEYSPACE.equals(k)) { + if (AuditingTypesConstants.janusGraph_KEYSPACE.equals(k)) { // session.execute("") } else if (AuditingTypesConstants.ARTIFACT_KEYSPACE.equals(k)) { 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 99acb3b62b..e40b5aa237 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 @@ -26,7 +26,7 @@ import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; @Configuration -@Import({TitanSpringConfig.class}) +@Import({JanusGraphSpringConfig.class}) @ComponentScan({ "org.openecomp.sdc.be.dao.cassandra", "org.openecomp.sdc.be.dao.neo4j", diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/JanusGraphSpringConfig.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/JanusGraphSpringConfig.java new file mode 100644 index 0000000000..d30caf1845 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/JanusGraphSpringConfig.java @@ -0,0 +1,54 @@ +package org.openecomp.sdc.be.dao.config; + +import org.openecomp.sdc.be.dao.DAOJanusGraphStrategy; +import org.openecomp.sdc.be.dao.JanusGraphClientStrategy; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; +import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient; +import org.openecomp.sdc.be.dao.janusgraph.transactions.SimpleJanusGraphTransactionManager; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@ComponentScan({ + "org.openecomp.sdc.be.dao.jsongraph", +}) +@EnableTransactionManagement +public class JanusGraphSpringConfig { + + @Bean(name = "janusgraph-generic-dao") + @Primary + public HealingJanusGraphGenericDao janusGraphGenericDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) { + return new HealingJanusGraphGenericDao(janusGraphClient); + } + + @Bean(name = "janusgraph-client", initMethod = "createGraph") + @Primary + public JanusGraphClient janusGraphClient(@Qualifier("dao-client-strategy") + JanusGraphClientStrategy janusGraphClientStrategy) { + return new JanusGraphClient(janusGraphClientStrategy); + } + + @Bean(name = "dao-client-strategy") + public JanusGraphClientStrategy janusGraphClientStrategy() { + return new DAOJanusGraphStrategy(); + } + + @Bean + public PlatformTransactionManager txManager() { + return new SimpleJanusGraphTransactionManager(janusGraphClient(janusGraphClientStrategy())); + } + + @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/config/TitanSpringConfig.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java deleted file mode 100644 index 34a860ddd2..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/config/TitanSpringConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -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.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; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@ComponentScan({ - "org.openecomp.sdc.be.dao.jsongraph", -}) -@EnableTransactionManagement -public class TitanSpringConfig { - - @Bean(name = "titan-generic-dao") - @Primary - public HealingTitanGenericDao titanGenericDao(@Qualifier("titan-client") TitanGraphClient titanGraphClient) { - return new HealingTitanGenericDao(titanGraphClient); - } - - @Bean(name = "titan-client", initMethod = "createGraph") - @Primary - public TitanGraphClient titanGraphClient(@Qualifier("dao-client-strategy") TitanClientStrategy titanClientStrategy) { - return new TitanGraphClient(titanClientStrategy); - } - - @Bean(name = "dao-client-strategy") - public TitanClientStrategy titanClientStrategy() { - return new DAOTitanStrategy(); - } - - @Bean - 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/impl/HealingPipelineDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/HealingPipelineDao.java index 5b219b2371..f757b58455 100644 --- 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 @@ -20,7 +20,7 @@ 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 org.janusgraph.core.JanusGraphVertex; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -33,7 +33,7 @@ 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.HealJanusGraphDao; 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; @@ -58,7 +58,7 @@ public class HealingPipelineDao { private HealGraphDao healNodeGraphDao; private HealGraphDao healVertexGraphDao; - private HealGraphDao healTitanVertexGraphDao; + private HealGraphDao healJanusGraphVertexGraphDao; public HealingPipelineDao() { healingPipeline = ImmutableListMultimap.of(); @@ -74,7 +74,7 @@ public class HealingPipelineDao { public void initGraphHealers() { healNodeGraphDao = new HealNodeGraphDao(this); healVertexGraphDao = new HealVertexGraphDao(this); - healTitanVertexGraphDao = new HealTitanGraphDao(this); + healJanusGraphVertexGraphDao = new HealJanusGraphDao(this); } @@ -85,8 +85,8 @@ public class HealingPipelineDao { if (graphNode instanceof GraphElement) { return healNodeGraphDao; } - if (graphNode instanceof TitanVertex) { - return healTitanVertexGraphDao; + if (graphNode instanceof JanusGraphVertex) { + return healJanusGraphVertexGraphDao; } return null; @@ -133,7 +133,7 @@ public class HealingPipelineDao { graphVertex.addMetadataProperty(GraphPropertyEnum.HEALING_VERSION, currentHealVersion.getVersion()); } - public void setHealingVersion(TitanVertex graphVertex) { + public void setHealingVersion(JanusGraphVertex graphVertex) { graphVertex.property(GraphPropertyEnum.HEALING_VERSION.getProperty(), currentHealVersion.getVersion()); } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealJanusGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealJanusGraphDao.java new file mode 100644 index 0000000000..76be4a6e12 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealJanusGraphDao.java @@ -0,0 +1,38 @@ +package org.openecomp.sdc.be.dao.impl.heal; + +import org.janusgraph.core.JanusGraphVertex; +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 HealJanusGraphDao implements HealGraphDao { + + private HealingPipelineDao healingPipelineDao; + + public HealJanusGraphDao(HealingPipelineDao healingPipelineDao) { + this.healingPipelineDao = healingPipelineDao; + } + + @Override + public JanusGraphVertex performGraphReadHealing(JanusGraphVertex 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 JanusGraphVertex healGraphVertex(JanusGraphVertex 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/HealNodeGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealNodeGraphDao.java index 2fc5c8fc5d..9bc75a0ba1 100644 --- 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 @@ -20,12 +20,12 @@ public class HealNodeGraphDao implements HealGraphDao { 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)); + healingPipelineDao.getHealersForVertex(graphEdge.getEdgeType().getProperty(), healingVersion).forEach(heal -> healJanusGraphVertex(childVertex, heal)); childVertex.setHealingVersion(healingPipelineDao.getCurrentHealVersion().getVersion()); return childVertex; } - private GraphNode healTitanVertex(GraphNode childVertex, Heal heal) { + private GraphNode healJanusGraphVertex(GraphNode childVertex, Heal heal) { heal.healData(childVertex); final HealVersion healVersion = heal.fromVersion(); HealVersion newerVersion = HealVersionBuilder.build(healVersion.getVersion() + 1); 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 deleted file mode 100644 index 1e33c61b9f..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/heal/HealTitanGraphDao.java +++ /dev/null @@ -1,38 +0,0 @@ -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/janusgraph/HealingJanusGraphGenericDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/HealingJanusGraphGenericDao.java new file mode 100644 index 0000000000..f8ab531f04 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/HealingJanusGraphGenericDao.java @@ -0,0 +1,126 @@ +/* + * 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.janusgraph; + +import org.janusgraph.core.JanusGraphVertex; +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.HealConstants; +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("janusgraph-generic-dao") +public class HealingJanusGraphGenericDao extends JanusGraphGenericDao { + + @Autowired + private HealingPipelineDao healingPipelineDao; + + public HealingJanusGraphGenericDao(JanusGraphClient janusGraphClient) { + super(janusGraphClient); + } + + @Override + public ImmutablePair getChildVertex(JanusGraphVertex childVertex, GraphEdgeLabels edgeType) { + ImmutablePair childVertexEdgeImmutablePair = super.getChildVertex(childVertex, edgeType); + final JanusGraphVertex graphVertex = childVertexEdgeImmutablePair.left; + healingPipelineDao.performGraphReadHealing(graphVertex, edgeType); + healingPipelineDao.setHealingVersion(graphVertex); + return childVertexEdgeImmutablePair; + } + + @Override + public Either>, JanusGraphOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, boolean withEdges) { + Either>, JanusGraphOperationStatus> 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, JanusGraphOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + Either, JanusGraphOperationStatus> 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>, JanusGraphOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) { + Either>, JanusGraphOperationStatus> 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(); + JanusGraphVertex 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 JanusGraphOperationStatus 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/janusgraph/JanusGraphClient.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphClient.java new file mode 100644 index 0000000000..5be907cc86 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphClient.java @@ -0,0 +1,412 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao.janusgraph; + +import org.janusgraph.core.*; +import org.janusgraph.core.schema.ConsistencyModifier; +import org.janusgraph.core.schema.JanusGraphIndex; +import org.janusgraph.core.schema.JanusGraphManagement; +import org.janusgraph.diskstorage.BackendException; +import org.janusgraph.diskstorage.ResourceUnavailableException; +import org.janusgraph.diskstorage.locking.PermanentLockingException; +import org.janusgraph.graphdb.database.idassigner.IDPoolExhaustedException; +import fj.data.Either; +import org.apache.commons.configuration.BaseConfiguration; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.DAOJanusGraphStrategy; +import org.openecomp.sdc.be.dao.JanusGraphClientStrategy; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.*; + + +@Component("janusgraph-client") +public class JanusGraphClient { + private static Logger logger = LoggerFactory.getLogger(JanusGraphClient.class.getName()); + private static Logger healthLogger = LoggerFactory.getLogger("janusgraph.healthcheck"); + + private static final String HEALTH_CHECK = GraphPropertiesDictionary.HEALTH_CHECK.getProperty(); + private static final String OK = "GOOD"; + + public JanusGraphClient() { + } + + private class HealthCheckTask implements Callable { + @Override + public Vertex call() { + + JanusGraphVertex v = (JanusGraphVertex) graph.query().has(HEALTH_CHECK, OK).vertices().iterator().next(); + JanusGraphVertexProperty property = v.property("healthcheck", OK + "_" + System.currentTimeMillis()); + healthLogger.trace("Health Check Node Found...{}", v.property(HEALTH_CHECK)); + graph.tx().commit(); + + return v; + } + } + + private class HealthCheckScheduledTask implements Runnable { + @Override + public void run() { + healthLogger.trace("Executing janusGraph Health Check Task - Start"); + boolean healthStatus = isGraphOpen(); + healthLogger.trace("Executing janusGraph Health Check Task - Status = {}", healthStatus); + if (healthStatus != lastHealthState) { + logger.trace("janusGraph Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus); + lastHealthState = healthStatus; + logAlarm(); + } + } + } + + private class ReconnectTask implements Runnable { + @Override + public void run() { + logger.trace("Trying to reconnect to JanusGraph..."); + if (graph == null) { + createGraph(janusGraphCfgFile); + } + } + } + + private JanusGraph graph; + + // Health Check Variables + + /** + * This executor will execute the health check task on a callable task that can be executed with a timeout. + */ + ExecutorService healthCheckExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "JanusGraph-Health-Check-Thread"); + } + }); + private long healthCheckReadTimeout = 2; + HealthCheckTask healthCallableTask = new HealthCheckTask(); + HealthCheckScheduledTask healthCheckScheduledTask = new HealthCheckScheduledTask(); + boolean lastHealthState = false; + + // Reconnection variables + private ScheduledExecutorService reconnectScheduler = null; + private ScheduledExecutorService healthCheckScheduler = null; + private Runnable reconnectTask = null; + private long reconnectInterval = 3; + @SuppressWarnings("rawtypes") + private Future reconnectFuture; + + private String janusGraphCfgFile = null; + JanusGraphClientStrategy janusGraphClientStrategy; + + public JanusGraphClient(JanusGraphClientStrategy janusGraphClientStrategy) { + super(); + this.janusGraphClientStrategy = janusGraphClientStrategy; + + // Initialize a single threaded scheduler for health-check + this.healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "JanusGraph-Health-Check-Task"); + } + }); + + healthCheckReadTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphHealthCheckReadTimeout(2); + reconnectInterval = ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphReconnectIntervalInSeconds(3); + + logger.info("** JanusGraphClient created"); + } + + @PostConstruct + public JanusGraphOperationStatus createGraph() { + + logger.info("** createGraph started **"); + + if (ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphInMemoryGraph()) { + BaseConfiguration conf = new BaseConfiguration(); + conf.setProperty("storage.backend", "inmemory"); + graph = JanusGraphFactory.open(conf); + createJanusGraphSchema(); + logger.info("** in memory graph created"); + return JanusGraphOperationStatus.OK; + } else { + this.janusGraphCfgFile = janusGraphClientStrategy.getConfigFile(); + if (janusGraphCfgFile == null || janusGraphCfgFile.isEmpty()) { + janusGraphCfgFile = "config/janusgraph.properties"; + } + + // yavivi + // In case connection failed on init time, schedule a reconnect task + // in the BG + JanusGraphOperationStatus status = createGraph(janusGraphCfgFile); + logger.debug("Create JanusGraph graph status {}", status); + if (status != JanusGraphOperationStatus.OK) { + this.startReconnectTask(); + } + + return status; + } + } + + private void startHealthCheckTask() { + this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS); + } + + /** + * This method will be invoked ONLY on init time in case JanusGraph storage is down. + */ + private void startReconnectTask() { + this.reconnectTask = new ReconnectTask(); + // Initialize a single threaded scheduler + this.reconnectScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "JanusGraph-Reconnect-Task"); + } + }); + + logger.info("Scheduling reconnect task {} with interval of {} seconds", reconnectTask, reconnectInterval); + reconnectFuture = this.reconnectScheduler.scheduleAtFixedRate(this.reconnectTask, 0, this.reconnectInterval, TimeUnit.SECONDS); + } + + public void cleanupGraph() { + if (graph != null) { + // graph.shutdown(); + graph.close(); + try { + JanusGraphFactory.drop(graph); + } catch (BackendException e) { + e.printStackTrace(); + } + } + } + + private boolean graphInitialized(){ + JanusGraphManagement graphMgmt = graph.openManagement(); + return graphMgmt.containsPropertyKey(HEALTH_CHECK) && graphMgmt.containsGraphIndex(HEALTH_CHECK); + } + + + public JanusGraphOperationStatus createGraph(String janusGraphCfgFile) { + logger.info("** open graph with {} started", janusGraphCfgFile); + try { + logger.info("openGraph : try to load file {}", janusGraphCfgFile); + graph = JanusGraphFactory.open(janusGraphCfgFile); + if (graph.isClosed() || !graphInitialized()) { + logger.error("janusgraph graph was not initialized"); + return JanusGraphOperationStatus.NOT_CREATED; + } + + } catch (Exception e) { + this.graph = null; + logger.info("createGraph : failed to open JanusGraph graph with configuration file: {}", janusGraphCfgFile); + logger.debug("createGraph : failed with exception.", e); + return JanusGraphOperationStatus.NOT_CONNECTED; + } + + logger.info("** JanusGraph graph created "); + + // Do some post creation actions + this.onGraphOpened(); + + return JanusGraphOperationStatus.OK; + } + + private void onGraphOpened() { + // if a reconnect task is running, cancel it. + if (this.reconnectFuture != null) { + logger.info("** Cancelling JanusGraph reconnect task"); + reconnectFuture.cancel(true); + } + + // create health-check node + if (!graph.query().has(HEALTH_CHECK, OK).vertices().iterator().hasNext()) { + logger.trace("Healthcheck Singleton node does not exist, Creating healthcheck node..."); + Vertex healthCheckNode = graph.addVertex(); + healthCheckNode.property(HEALTH_CHECK, OK); + logger.trace("Healthcheck node created successfully. ID={}", healthCheckNode.property(T.id.getAccessor())); + graph.tx().commit(); + } else { + logger.trace("Skipping Healthcheck Singleton node creation. Already exist..."); + } + this.startHealthCheckTask(); + } + + + public Either getGraph() { + if (graph != null) { + return Either.left(graph); + } else { + return Either.right(JanusGraphOperationStatus.NOT_CREATED); + } + } + + public JanusGraphOperationStatus commit() { + if (graph != null) { + try { + graph.tx().commit(); + return JanusGraphOperationStatus.OK; + } catch (Exception e) { + return handleJanusGraphException(e); + } + } else { + return JanusGraphOperationStatus.NOT_CREATED; + } + } + + public JanusGraphOperationStatus rollback() { + if (graph != null) { + try { + // graph.rollback(); + graph.tx().rollback(); + return JanusGraphOperationStatus.OK; + } catch (Exception e) { + return handleJanusGraphException(e); + } + } else { + return JanusGraphOperationStatus.NOT_CREATED; + } + } + + public static JanusGraphOperationStatus handleJanusGraphException(Exception e) { + if (e instanceof JanusGraphConfigurationException) { + return JanusGraphOperationStatus.JANUSGRAPH_CONFIGURATION; + } + if (e instanceof SchemaViolationException) { + return JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION; + } + if (e instanceof PermanentLockingException) { + return JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION; + } + if (e instanceof IDPoolExhaustedException) { + return JanusGraphOperationStatus.GENERAL_ERROR; + } + if (e instanceof InvalidElementException) { + return JanusGraphOperationStatus.INVALID_ELEMENT; + } + if (e instanceof InvalidIDException) { + return JanusGraphOperationStatus.INVALID_ID; + } + if (e instanceof QueryException) { + return JanusGraphOperationStatus.INVALID_QUERY; + } + if (e instanceof ResourceUnavailableException) { + return JanusGraphOperationStatus.RESOURCE_UNAVAILABLE; + } + if (e instanceof IllegalArgumentException) { + // TODO check the error message?? + return JanusGraphOperationStatus.ILLEGAL_ARGUMENT; + } + + return JanusGraphOperationStatus.GENERAL_ERROR; + } + + public boolean getHealth() { + return this.lastHealthState; + } + + private boolean isGraphOpen() { + healthLogger.trace("Invoking JanusGraph health check ..."); + Vertex v = null; + if (graph != null) { + try { + Future future = healthCheckExecutor.submit(healthCallableTask); + v = future.get(this.healthCheckReadTimeout, TimeUnit.SECONDS); + healthLogger.trace("Health Check Node Found... {}", v.property(HEALTH_CHECK)); + graph.tx().commit(); + } catch (Exception e) { + String message = e.getMessage(); + if (message == null) { + message = e.getClass().getName(); + } + logger.error("JanusGraph Health Check Failed. {}", message); + return false; + } + return true; + } else { + return false; + } + } + + + public static void main(String[] args) throws InterruptedException { + JanusGraphClient client = new JanusGraphClient(new DAOJanusGraphStrategy()); + client.createGraph(); + + while (true) { + boolean health = client.isGraphOpen(); + System.err.println("health=" + health); + Thread.sleep(2000); + } + + } + + + private static final String JANUSGRAPH_HEALTH_CHECK = "janusgraphHealthCheck"; + + private void logAlarm() { + if (lastHealthState) { + BeEcompErrorManager.getInstance().logBeHealthCheckJanusGraphRecovery(JANUSGRAPH_HEALTH_CHECK); + } else { + BeEcompErrorManager.getInstance().logBeHealthCheckJanusGraphError(JANUSGRAPH_HEALTH_CHECK); + } + } + + private void createJanusGraphSchema() { + + JanusGraphManagement graphMgt = graph.openManagement(); + JanusGraphIndex index = null; + for (GraphPropertiesDictionary prop : GraphPropertiesDictionary.values()) { + PropertyKey propKey = null; + if (!graphMgt.containsPropertyKey(prop.getProperty())) { + Class clazz = prop.getClazz(); + if (!clazz.isAssignableFrom(ArrayList.class) && !clazz.isAssignableFrom(HashMap.class)) { + propKey = graphMgt.makePropertyKey(prop.getProperty()).dataType(prop.getClazz()).make(); + } + } else { + propKey = graphMgt.getPropertyKey(prop.getProperty()); + } + if (prop.isIndexed()) { + if (!graphMgt.containsGraphIndex(prop.getProperty())) { + if (prop.isUnique()) { + index = graphMgt.buildIndex(prop.getProperty(), Vertex.class).addKey(propKey).unique().buildCompositeIndex(); + // Ensures only one name per vertex + graphMgt.setConsistency(propKey, ConsistencyModifier.LOCK); + // Ensures name uniqueness in the graph + graphMgt.setConsistency(index, ConsistencyModifier.LOCK); + + } else { + graphMgt.buildIndex(prop.getProperty(), Vertex.class).addKey(propKey).buildCompositeIndex(); + } + } + } + } + graphMgt.commit(); + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphGenericDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphGenericDao.java new file mode 100644 index 0000000000..591d7f32d7 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphGenericDao.java @@ -0,0 +1,1770 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao.janusgraph; + +import org.janusgraph.core.PropertyKey; +import org.janusgraph.core.JanusGraphEdge; +import org.janusgraph.core.JanusGraph; +import org.janusgraph.core.JanusGraphQuery; +import org.janusgraph.core.JanusGraphVertex; +import org.janusgraph.core.JanusGraphVertexQuery; +import org.janusgraph.graphdb.query.JanusGraphPredicate; +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.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.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.beans.factory.annotation.Qualifier; + +public class JanusGraphGenericDao { + + private static final String FAILED_TO_RETRIEVE_GRAPH_STATUS_IS = "Failed to retrieve graph. status is {}"; + private static final String NO_EDGES_IN_GRAPH_FOR_CRITERIA = "No edges in graph for criteria"; + private static final String FAILED_TO_CREATE_EDGE_FROM_TO = "Failed to create edge from [{}] to [{}]"; + private JanusGraphClient janusGraphClient; + private static Logger log = Logger.getLogger(JanusGraphGenericDao.class.getName()); + private static final String LOCK_NODE_PREFIX = "lock_"; + + public JanusGraphGenericDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) { + this.janusGraphClient = janusGraphClient; + log.info("** JanusGraphGenericDao created"); + } + + public JanusGraphOperationStatus commit() { + log.debug("doing commit."); + return janusGraphClient.commit(); + } + + public JanusGraphOperationStatus rollback() { + log.error("Going to execute rollback on graph."); + return janusGraphClient.rollback(); + } + + public void handleTransactionCommitRollback(boolean inTransaction, Either result) { + if (!inTransaction) { + if (result == null || result.isRight()) { + rollback(); + } else { + commit(); + } + } + } + + public Either getGraph() { + return janusGraphClient.getGraph(); + } + + // For healthCheck + public boolean isGraphOpen() { + return janusGraphClient.getHealth(); + } + + /** + * + * @param node + * @param clazz + * @return + */ + public Either createNode(T node, Class clazz) { + log.debug("try to create node for ID [{}]", node.getKeyValueId()); + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + T newNode; + try { + JanusGraph tGraph = graph.left().value(); + + Vertex vertex = tGraph.addVertex(); + + vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel()); + + Map properties = node.toGraphMap(); + if (properties != null) { + setProperties(vertex, properties); + } + Map newProps = getProperties(vertex); + newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz); + log.debug("created node for props : {}", newProps); + log.debug("Node was created for ID [{}]", node.getKeyValueId()); + return Either.left(newNode); + + } catch (Exception e) { + log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value()); + return Either.right(graph.right().value()); + } + } + + public Either createNode(GraphNode node) { + log.debug("try to create node for ID [{}]", node.getKeyValueId()); + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphVertex vertex = tGraph.addVertex(); + + vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel()); + + Map properties = node.toGraphMap(); + if (properties != null) { + setProperties(vertex, properties); + } + log.debug("Node was created for ID [{}]", node.getKeyValueId()); + return Either.left(vertex); + + } catch (Exception e) { + log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value()); + return Either.right(graph.right().value()); + } + } + + /** + * + * @param relation + * @return + */ + public Either createRelation(GraphRelation relation) { + log.debug("try to create relation from [{}] to [{}] ", relation.getFrom(), relation.getTo()); + + RelationEndPoint from = relation.getFrom(); + RelationEndPoint to = relation.getTo(); + ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); + ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); + + return createEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap()); + + } + + private Either createEdge(String type, ImmutablePair from, ImmutablePair to, String fromLabel, String toLabel, Map properties) { + Either graph = janusGraphClient.getGraph(); + + if (graph.isLeft()) { + try { + Either fromV = getVertexByPropertyAndLabel(from.getKey(), from.getValue(), fromLabel); + if (fromV.isRight()) { + JanusGraphOperationStatus error = fromV.right().value(); + if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } else { + return Either.right(error); + } + } + Either toV = getVertexByPropertyAndLabel(to.getKey(), to.getValue(), toLabel); + if (toV.isRight()) { + JanusGraphOperationStatus error = toV.right().value(); + if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } else { + return Either.right(error); + } + } + + Vertex fromVertex = fromV.left().value(); + Vertex toVertex = toV.left().value(); + Edge edge = fromVertex.addEdge(type, toVertex); + + if (properties != null) { + + setProperties(edge, properties); + } + + Vertex vertexOut = edge.outVertex(); + Vertex vertexIn = edge.inVertex(); + + GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); + GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); + + GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); + + return Either.left(newRelation); + } catch (Exception e) { + log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, from, to, e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + log.debug("Failed to create edge from [{}] to [{}] {}", from, to, graph.right().value()); + return Either.right(graph.right().value()); + } + } + + public JanusGraphOperationStatus createEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { + try { + Edge edge = addEdge(vertexOut, vertexIn, type, properties); + } catch (Exception e) { + log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e); + return JanusGraphClient.handleJanusGraphException(e); + } + return JanusGraphOperationStatus.OK; + + } + + private Edge addEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { + Edge edge = vertexOut.addEdge(type.getProperty(), vertexIn); + + if (properties != null) { + + setProperties(edge, properties); + } + return edge; + } + + /** + * creates an identical edge in the graph + * @param edge + * @return the copy operation status + */ + public Either copyEdge(Vertex out, Vertex in, Edge edge) { + GraphEdgeLabels byName = GraphEdgeLabels.getByName(edge.label()); + return this.saveEdge(out, in, byName, edgePropertiesToMap(edge)); + } + + private Map edgePropertiesToMap(Edge edge) { + Iterable> propertiesIterable = edge::properties; + return StreamSupport.stream(propertiesIterable.spliterator(), false).collect(Collectors.toMap(Property::key, Property::value)); + } + + public Either saveEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { + try { + Edge edge = addEdge(vertexOut, vertexIn, type, properties); + return Either.left(edge); + } catch (Exception e) { + log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } + + public JanusGraphOperationStatus createEdge(JanusGraphVertex vertexOut, GraphNode to, GraphEdgeLabels type, Map properties) { + + JanusGraphVertex vertexIn; + Either toV = getVertexByPropertyAndLabel(to.getUniqueIdKey(), to.getUniqueId(), to.getLabel()); + if (toV.isRight()) { + JanusGraphOperationStatus error = toV.right().value(); + if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) { + return JanusGraphOperationStatus.INVALID_ID; + } else { + return error; + } + } + vertexIn = (JanusGraphVertex) toV.left().value(); + return createEdge(vertexOut, vertexIn, type, properties); + } + + /** + * + * @param from + * @param to + * @param label + * @param properties + * @return + */ + public Either createRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map properties) { + log.debug("try to create relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); + return createEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties); + } + + public Either replaceRelationLabel(GraphNode from, GraphNode to, GraphEdgeLabels label, GraphEdgeLabels newLabel) { + + log.debug("try to replace relation {} to {} from [{}] to [{}]", label.name(), newLabel.name(), from.getKeyValueId(), to.getKeyValueId()); + Either getRelationResult = getRelation(from, to, label); + if (getRelationResult.isRight()) { + return getRelationResult; + } + + GraphRelation origRelation = getRelationResult.left().value(); + Either createRelationResult = createRelation(from, to, newLabel, origRelation.toGraphMap()); + if (createRelationResult.isRight()) { + return createRelationResult; + } + + Either deleteRelationResult = deleteRelation(origRelation); + if (deleteRelationResult.isRight()) { + return deleteRelationResult; + } + return Either.left(createRelationResult.left().value()); + } + + /** + * + * @param keyName + * @param keyValue + * @param clazz + * @return + */ + public Either getNode(String keyName, Object keyValue, Class clazz) { + + log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue); + + Either vertexByProperty = getVertexByProperty(keyName, keyValue); + + if (vertexByProperty.isLeft()) { + try { + Vertex vertex = vertexByProperty.left().value(); + Map properties = getProperties(vertex); + T node = GraphElementFactory.createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties, clazz); + return Either.left(node); + } catch (Exception e) { + log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value()); + return Either.right(vertexByProperty.right().value()); + } + } + + /** + * + * @param from + * @param to + * @param label + * @return + */ + public Either getRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) { + log.debug("try to get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); + + Either edge = getEdgeByNodes(from, to, label); + + if (edge.isLeft()) { + try { + Map properties = getProperties(edge.left().value()); + GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, from, to); + return Either.left(relation); + } catch (Exception e) { + log.debug("Failed to get get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + log.debug("Failed to get get relation from [{}] to [{}] {}", from.getKeyValueId(), to.getKeyValueId(), edge.right().value()); + return Either.right(edge.right().value()); + } + } + + public Either getEdgeByNodes(GraphNode from, GraphNode to, GraphEdgeLabels label) { + ImmutablePair keyValueIdFrom = from.getKeyValueId(); + ImmutablePair keyValueIdTo = to.getKeyValueId(); + + return getEdgeByVerticies(keyValueIdFrom.getKey(), keyValueIdFrom.getValue(), keyValueIdTo.getKey(), keyValueIdTo.getValue(), label.getProperty()); + } + + public Either deleteIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { + + Either edgeByCriteria = getIncomingEdgeByCriteria(to, label, props); + if (edgeByCriteria.isLeft()) { + Either graph = getGraph(); + if (graph.isLeft()) { + Edge edge = edgeByCriteria.left().value(); + log.debug("delete edge {} to {} ", label.getProperty(), to.getUniqueId()); + edge.remove(); + Map properties = getProperties(edge); + Vertex fromVertex = edge.outVertex(); + String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); + GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class); + GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to); + return Either.left(relation); + } else { + log.debug("failed to get graph"); + return Either.right(graph.right().value()); + } + + } else { + log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId()); + return Either.right(edgeByCriteria.right().value()); + } + + } + + public Either getIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { + + Either edgeByCriteria = getIncomingEdgeByCriteria(to, label, props); + if (edgeByCriteria.isLeft()) { + Either graph = getGraph(); + if (graph.isLeft()) { + Edge edge = edgeByCriteria.left().value(); + Map properties = getProperties(edge); + Vertex fromVertex = edge.outVertex(); + String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); + GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class); + GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to); + return Either.left(relation); + } else { + log.debug("failed to get graph"); + return Either.right(graph.right().value()); + } + + } else { + log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId()); + return Either.right(edgeByCriteria.right().value()); + } + + } + + public Either getIncomingEdgeByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { + + ImmutablePair keyValueIdTo = to.getKeyValueId(); + + Either vertexFrom = getVertexByProperty(keyValueIdTo.getKey(), keyValueIdTo.getValue()); + if (vertexFrom.isRight()) { + return Either.right(vertexFrom.right().value()); + } + Vertex vertex = vertexFrom.left().value(); + JanusGraphVertex janusGraphVertex = (JanusGraphVertex) vertex; + JanusGraphVertexQuery query = janusGraphVertex.query(); + query = query.labels(label.getProperty()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + Edge matchingEdge = null; + Iterable edges = query.edges(); + if (edges == null) { + log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + Iterator eIter = edges.iterator(); + if (eIter.hasNext()) { + matchingEdge = eIter.next(); + } + + if (matchingEdge == null) { + log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + return Either.left(matchingEdge); + } + + public Either getEdgeByVerticies(String keyNameFrom, Object keyValueFrom, String keyNameTo, Object keyValueTo, String label) { + Either graph = janusGraphClient.getGraph(); + + if (graph.isLeft()) { + try { + Either vertexFrom = getVertexByProperty(keyNameFrom, keyValueFrom); + if (vertexFrom.isRight()) { + return Either.right(vertexFrom.right().value()); + } + Iterable edges = vertexFrom.left().value().query().labels(label).edges(); + Iterator eIter = edges.iterator(); + while (eIter.hasNext()) { + Edge edge = eIter.next(); + Vertex vertexIn = edge.inVertex(); + if (vertexIn.value(keyNameTo) != null && vertexIn.value(keyNameTo).equals(keyValueTo) && label.equals(edge.label())) { + return Either.left(edge); + } + } + log.debug("No relation in graph from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } catch (Exception e) { + log.debug("Failed to get get relation from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo, e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getEdgesForNode(GraphNode node, Direction requestedDirection) { + + Either, JanusGraphOperationStatus> result; + + ImmutablePair keyValueId = node.getKeyValueId(); + Either eitherVertex = getVertexByProperty(keyValueId.getKey(), keyValueId.getValue()); + + if (eitherVertex.isLeft()) { + List edges = prepareEdgesList(eitherVertex.left().value(), requestedDirection); + + result = Either.left(edges); + } else { + result = Either.right(eitherVertex.right().value()); + } + return result; + } + + private List prepareEdgesList(Vertex vertex, Direction requestedDirection) { + List edges = new ArrayList<>(); + Iterator edgesItr = ((JanusGraphVertex) vertex).query().edges().iterator(); + while (edgesItr.hasNext()) { + Edge edge = edgesItr.next(); + Direction currEdgeDirection = getEdgeDirection(vertex, edge); + if (currEdgeDirection == requestedDirection || requestedDirection == Direction.BOTH) { + edges.add(edge); + } + + } + return edges; + } + + private Direction getEdgeDirection(Vertex vertex, Edge edge) { + Direction result; + Vertex vertexOut = edge.outVertex(); + if (vertexOut.equals(vertex)) { + result = Direction.OUT; + } else { + result = Direction.IN; + + } + return result; + } + + /** + * + * @param from + * @param to + * @param label + * @param properties + * @return + */ + public Either updateRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map properties) { + log.debug("try to update relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); + return updateEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties); + } + + private Either updateEdge(String type, ImmutablePair from, ImmutablePair to, String fromLabel, String toLabel, Map properties) { + + Either edgeS = getEdgeByVerticies(from.getKey(), from.getValue(), to.getKey(), to.getValue(), type); + if (edgeS.isLeft()) { + + try { + Edge edge = edgeS.left().value(); + if (properties != null) { + setProperties(edge, properties); + } + + Vertex vertexOut = edge.outVertex(); + Vertex vertexIn = edge.inVertex(); + + GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); + GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); + + GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); + if (log.isDebugEnabled()) { + log.debug("Relation was updated from [{}] to [{}] ", from, to); + } + return Either.left(newRelation); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to update relation from [{}] to [{}] ", from, to, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to update relation from [{}] to [{}] {}", from, to, edgeS.right().value()); + } + return Either.right(edgeS.right().value()); + } + } + + /** + * + * @param relation + * @return + */ + public Either updateRelation(GraphRelation relation) { + log.debug("try to update relation from [{}] to [{}]", relation.getFrom(), relation.getTo()); + RelationEndPoint from = relation.getFrom(); + RelationEndPoint to = relation.getTo(); + ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); + ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); + + return updateEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap()); + + } + + private Either getVertexByPropertyAndLabel(String name, Object value, String label) { + + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable vertecies = tGraph.query().has(name, value).has(GraphPropertiesDictionary.LABEL.getProperty(), label).vertices(); + + java.util.Iterator iterator = vertecies.iterator(); + if (iterator.hasNext()) { + Vertex vertex = iterator.next(); + return Either.left(vertex); + } + if (log.isDebugEnabled()) { + log.debug("No vertex in graph for key =" + name + " and value = " + value + " label = " + label); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to get vertex in graph for key ={} and value = {} label = {}",name,value,label); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (log.isDebugEnabled()) { + log.debug("No vertex in graph for key ={} and value = {} label = {} error : {}",name,value,label,graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either getVertexByProperty(String name, Object value) { + + Either graph = janusGraphClient.getGraph(); + if (value == null) { + if (log.isDebugEnabled()) { + log.debug("No vertex in graph for key = {} and value = {}", name, value); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable vertecies = tGraph.query().has(name, value).vertices(); + + java.util.Iterator iterator = vertecies.iterator(); + if (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + return Either.left(vertex); + } else { + if (log.isDebugEnabled()) { + log.debug("No vertex in graph for key ={} and value = {}", name, value); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to get vertex in graph for key = {} and value = ", name, value); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + if (log.isDebugEnabled()) { + log.debug("No vertex in graph for key = {} and value = {} error : {}", name, value, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Map hasProps, Map hasNotProps, Class clazz) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + + if (hasProps != null && !hasProps.isEmpty()) { + for (Map.Entry entry : hasProps.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + if (hasNotProps != null && !hasNotProps.isEmpty()) { + for (Map.Entry entry : hasNotProps.entrySet()) { + query = query.hasNot(entry.getKey(), entry.getValue()); + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map newProp = getProperties(vertex); + + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (log.isDebugEnabled()) { + log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties has = {}, properties hasNot = {} is {}", type, hasProps, hasNotProps, result.size()); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(result); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type = {}", type, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Class clazz, List> props) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + for (ImmutableTriple prop : props) { + if (QueryType.HAS.equals(prop.getLeft())) { + query = query.has(prop.getMiddle(), prop.getRight()); + } else { + query = query.hasNot(prop.getMiddle(), prop.getRight()); + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map newProp = getProperties(vertex); + + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(result); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type = {}", type, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Map props, Class clazz) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map newProp = getProperties(vertex); + + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (log.isDebugEnabled()) { + log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(result); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getByCriteriaWithPredicate(NodeTypeEnum type, Map> props, Class clazz) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + + if (props != null && !props.isEmpty()) { + JanusGraphPredicate predicate = null; + Object object = null; + for (Map.Entry> entry : props.entrySet()) { + predicate = entry.getValue().getKey(); + object = entry.getValue().getValue(); + query = query.has(entry.getKey(), predicate, object); + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map newProp = getProperties(vertex); + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + if (log.isDebugEnabled()) { + log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props); + } + return Either.left(result); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (log.isDebugEnabled()) { + log.debug("Failed get by criteria for type = {} and properties = {} error : {}", type, props, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getAll(NodeTypeEnum type, Class clazz) { + return getByCriteria(type, null, clazz); + } + + /** + * + * @param node + * @param clazz + * @return + */ + public Either updateNode(GraphNode node, Class clazz) { + log.debug("Try to update node for {}", node.getKeyValueId()); + + ImmutablePair keyValueId = node.getKeyValueId(); + Either vertexByProperty = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel()); + + if (vertexByProperty.isLeft()) { + try { + Vertex vertex = vertexByProperty.left().value(); + + Map mapProps = node.toGraphMap(); + + for (Map.Entry entry : mapProps.entrySet()) { + if (!entry.getKey().equals(node.getUniqueIdKey())) { + vertex.property(entry.getKey(), entry.getValue()); + } + } + + Either vertexByPropertyAndLabel = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel()); + if (vertexByPropertyAndLabel.isRight()) { + return Either.right(vertexByPropertyAndLabel.right().value()); + } else { + Map newProp = getProperties(vertexByPropertyAndLabel.left().value()); + T updateNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProp, clazz); + return Either.left(updateNode); + } + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to update node for {}", node.getKeyValueId(), e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to update node for {} error :{}", node.getKeyValueId(), vertexByProperty.right().value()); + } + return Either.right(vertexByProperty.right().value()); + } + + } + + public JanusGraphOperationStatus updateVertex(GraphNode node, Vertex vertex) { + log.debug("Try to update node for {}", node.getKeyValueId()); + try { + + Map mapProps = node.toGraphMap(); + + for (Map.Entry entry : mapProps.entrySet()) { + if (!entry.getKey().equals(node.getUniqueIdKey())) { + vertex.property(entry.getKey(), entry.getValue()); + } + } + + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to update node for {}", node.getKeyValueId(), e); + } + return JanusGraphClient.handleJanusGraphException(e); + } + return JanusGraphOperationStatus.OK; + + } + + /** + * + * @param node + * @param clazz + * @return + */ + public Either deleteNode(GraphNode node, Class clazz) { + log.debug("Try to delete node for {}", node.getKeyValueId()); + ImmutablePair keyValueId = node.getKeyValueId(); + return deleteNode(keyValueId.getKey(), keyValueId.getValue(), clazz); + } + + /** + * + * @param keyName + * @param keyValue + * @param clazz + * @return + */ + public Either deleteNode(String keyName, Object keyValue, Class clazz) { + Either vertexByProperty = getVertexByProperty(keyName, keyValue); + + if (vertexByProperty.isLeft()) { + try { + Vertex vertex = vertexByProperty.left().value(); + + Map properties = getProperties(vertex); + if (properties != null) { + String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()); + + T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz); + if (node != null) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + JanusGraph tGraph = graph.left().value(); + vertex.remove(); + } else { + return Either.right(graph.right().value()); + } + return Either.left(node); + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue); + } + return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue); + } + return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL); + } + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to delete node for {} = {}", keyName, keyValue, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + return Either.right(vertexByProperty.right().value()); + } + } + + public Either deleteRelation(GraphRelation relation) { + log.debug("try to delete relation from [{}] to [{}]", relation.getFrom(), relation.getTo()); + RelationEndPoint from = relation.getFrom(); + RelationEndPoint to = relation.getTo(); + ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); + ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); + + return deleteEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName()); + + } + + public Either isRelationExist(GraphNode from, GraphNode to, GraphEdgeLabels edgeLabel) { + return getEdgeByNodes(from, to, edgeLabel) + .left() + .map(edge -> true) + .right() + .bind(err -> err == JanusGraphOperationStatus.NOT_FOUND ? Either.left(false): Either.right(err)); + } + + public Either deleteRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) { + log.debug("try to delete relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); + return deleteEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel()); + } + + private Either deleteEdge(String type, ImmutablePair fromKeyId, ImmutablePair toKeyId, String fromLabel, String toLabel) { + Either edgeS = getEdgeByVerticies(fromKeyId.getKey(), fromKeyId.getValue(), toKeyId.getKey(), toKeyId.getValue(), type); + if (edgeS.isLeft()) { + try { + Edge edge = edgeS.left().value(); + + Vertex vertexOut = edge.outVertex(); + Vertex vertexIn = edge.inVertex(); + + GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); + GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); + + GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); + + Either graph = janusGraphClient.getGraph(); + + if (graph.isLeft()) { + edge.remove(); + ; + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to delete relation {} from {} to {} error : {}",type,fromKeyId,toKeyId,graph.right().value()); + } + return Either.right(graph.right().value()); + } + return Either.left(newRelation); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Failed to delete relation {} from {} to {}", type, fromKeyId, toKeyId, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, edgeS.right().value()); + } + return Either.right(edgeS.right().value()); + } + } + + public void setJanusGraphClient(JanusGraphClient janusGraphClient) { + this.janusGraphClient = janusGraphClient; + } + + public Either deleteIncomingRelation(GraphRelation relation) { + + RelationEndPoint to = relation.getTo(); + ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); + + return deleteIncomingEdge(relation.getType(), toKeyId); + + } + + private Either deleteIncomingEdge(String type, ImmutablePair toKeyId) { + + Either graph = janusGraphClient.getGraph(); + + if (graph.isLeft()) { + Either rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue()); + if (rootVertexResult.isLeft()) { + Vertex rootVertex = rootVertexResult.left().value(); + Iterator edgesIterator = rootVertex.edges(Direction.IN, type); + if (edgesIterator != null) { + + Edge edge = null; + + if (edgesIterator.hasNext()) { + edge = edgesIterator.next(); + if (edgesIterator.hasNext()) { + return Either.right(JanusGraphOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL); + } + } else { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + log.debug("Find the tail vertex of the edge of type {} to vertex {}", type, toKeyId); + Vertex vertexOut = edge.outVertex(); + String fromLabel = vertexOut.value(GraphPropertiesDictionary.LABEL.getProperty()); + String toLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); + log.debug("The label of the outgoing vertex is {}", fromLabel); + GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); + + GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class); + + GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); + + edge.remove(); + + return Either.left(newRelation); + + } else { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + } else { + return Either.right(graph.right().value()); + } + + } else { + return Either.right(graph.right().value()); + } + + } + + public Either deleteOutgoingRelation(GraphRelation relation) { + + RelationEndPoint from = relation.getFrom(); + ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); + + return deleteOutgoingEdge(relation.getType(), fromKeyId); + + } + + private Either deleteOutgoingEdge(String type, ImmutablePair toKeyId) { + + Either graph = janusGraphClient.getGraph(); + + if (graph.isLeft()) { + Either rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue()); + if (rootVertexResult.isLeft()) { + Vertex rootVertex = rootVertexResult.left().value(); + Iterator edgesIterator = rootVertex.edges(Direction.OUT, type); + if (edgesIterator != null) { + + Edge edge = null; + + if (edgesIterator.hasNext()) { + edge = edgesIterator.next(); + if (edgesIterator.hasNext()) { + return Either.right(JanusGraphOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL); + } + } else { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + log.debug("Find the tail vertex of the edge of type {} to vertex ", type, toKeyId); + Vertex vertexIn = edge.inVertex(); + String toLabel = vertexIn.value(GraphPropertiesDictionary.LABEL.getProperty()); + String fromLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); + log.debug("The label of the tail vertex is {}", toLabel); + GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class); + + GraphNode nodeTo = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); + + GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeFrom, nodeTo); + + edge.remove(); + + return Either.left(newRelation); + + } else { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + } else { + return Either.right(graph.right().value()); + } + + } else { + return Either.right(graph.right().value()); + } + } + + /** + * + * @param id + * @return + */ + + public JanusGraphOperationStatus lockElement(String id, NodeTypeEnum type) { + + StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); + lockId.append(type.getName()).append("_").append(id); + return lockNode(lockId.toString()); + } + + public JanusGraphOperationStatus lockElement(GraphNode node) { + + StringBuffer lockId = createLockElementId(node); + + return lockNode(lockId.toString()); + } + + private JanusGraphOperationStatus lockNode(String lockId) { + JanusGraphOperationStatus status = JanusGraphOperationStatus.OK; + + GraphNodeLock lockNode = new GraphNodeLock(lockId); + + Either lockNodeNew = createNode(lockNode, GraphNodeLock.class); + if (lockNodeNew.isLeft()) { + log.debug("before commit, Lock node created for {}", lockId); + return janusGraphClient.commit(); + } else { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + JanusGraph tGraph = graph.left().value(); + Either vertex = getVertexByProperty(lockNode.getUniqueIdKey(), lockNode.getUniqueId()); + if (vertex.isLeft()) { + status = relockNode(lockNode, lockNodeNew, tGraph, vertex); + } else { + status = vertex.right().value(); + } + } else { + status = graph.right().value(); + } + } + return status; + } + + private JanusGraphOperationStatus relockNode(GraphNodeLock lockNode, Either lockNodeNew, JanusGraph tGraph, Either vertex) { + JanusGraphOperationStatus status = JanusGraphOperationStatus.OK; + Long time = vertex.left().value().value(GraphPropertiesDictionary.CREATION_DATE.getProperty()); + Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphLockTimeout(); + if (time + lockTimeout * 1000 < System.currentTimeMillis()) { + log.debug("Found not released lock node with id {}", lockNode.getUniqueId()); + vertex.left().value().remove(); + lockNodeNew = createNode(lockNode, GraphNodeLock.class); + if (lockNodeNew.isLeft()) { + log.debug("Lock node created for {}", lockNode.getUniqueIdKey()); + return janusGraphClient.commit(); + } else { + log.debug("Failed Lock node for {} . Commit transacton for deleted previous vertex .", lockNode.getUniqueIdKey()); + janusGraphClient.commit(); + status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew); + } + } else { + log.debug("Failed Lock node for {} rollback transacton", lockNode.getUniqueIdKey()); + janusGraphClient.rollback(); + status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew); + } + return status; + } + + public Either>, JanusGraphOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, boolean withEdges) { + + List> immutablePairs = new ArrayList<>(); + + Either graphRes = janusGraphClient.getGraph(); + if (graphRes.isRight()) { + log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); + return Either.right(graphRes.right().value()); + } + + JanusGraph janusGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = janusGraph.query().has(key, uniqueId).vertices(); + if (vertices == null || !vertices.iterator().hasNext()) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } + + Vertex rootVertex = vertices.iterator().next(); + + Iterator edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + GraphEdge graphEdge = null; + + if (withEdges) { + Map edgeProps = getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + } + + Vertex outgoingVertex = edge.inVertex(); + Map properties = getProperties(outgoingVertex); + T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); + + ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); + immutablePairs.add(immutablePair); + } + } + + if (immutablePairs.isEmpty()) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(immutablePairs); + + } + + public Either>, JanusGraphOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) { + + List> immutablePairs = new ArrayList<>(); + + Either graphRes = janusGraphClient.getGraph(); + if (graphRes.isRight()) { + log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); + return Either.right(graphRes.right().value()); + } + + JanusGraph janusGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = janusGraph.query().has(key, uniqueId).vertices(); + if (vertices == null || !vertices.iterator().hasNext()) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } + + Vertex rootVertex = vertices.iterator().next(); + + Iterator edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + JanusGraphVertex vertex = (JanusGraphVertex) edge.inVertex(); + + ImmutablePair immutablePair = new ImmutablePair<>(vertex, edge); + immutablePairs.add(immutablePair); + } + } + if (immutablePairs.isEmpty()) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(immutablePairs); + + } + + public Either>, JanusGraphOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + return this.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, true); + } + + private JanusGraphOperationStatus checkLockError(String lockId, Either lockNodeNew) { + JanusGraphOperationStatus status; + JanusGraphOperationStatus error = lockNodeNew.right().value(); + log.debug("Failed to Lock node for {} error = {}", lockId, error); + if (error.equals(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION) || error.equals( + JanusGraphOperationStatus.ILLEGAL_ARGUMENT)) { + status = JanusGraphOperationStatus.ALREADY_LOCKED; + } else { + status = error; + } + return status; + } + + /** + * + * @param node + * @return + */ + public JanusGraphOperationStatus releaseElement(GraphNode node) { + StringBuffer lockId = createLockElementId(node); + + return unlockNode(lockId); + } + + private JanusGraphOperationStatus unlockNode(StringBuffer lockId) { + GraphNodeLock lockNode = new GraphNodeLock(lockId.toString()); + + Either lockNodeNew = deleteNode(lockNode, GraphNodeLock.class); + if (lockNodeNew.isLeft()) { + log.debug("Lock node released for lock id = {}", lockId); + return janusGraphClient.commit(); + } else { + janusGraphClient.rollback(); + JanusGraphOperationStatus error = lockNodeNew.right().value(); + log.debug("Failed to Release node for lock id {} error = {}", lockId, error); + return error; + } + } + + public JanusGraphOperationStatus releaseElement(String id, NodeTypeEnum type) { + StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); + lockId.append(type.getName()).append("_").append(id); + return unlockNode(lockId); + } + + private StringBuffer createLockElementId(GraphNode node) { + StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); + lockId.append(node.getLabel()).append("_").append(node.getUniqueId()); + return lockId; + } + + public Either, JanusGraphOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + + Either>, JanusGraphOperationStatus> childrenNodes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); + + if (childrenNodes.isRight()) { + return Either.right(childrenNodes.right().value()); + } + + List> value = childrenNodes.left().value(); + + if (value.size() > 1) { + return Either.right(JanusGraphOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE); + } + + return Either.left(value.get(0)); + + } + + public ImmutablePair getChildVertex(JanusGraphVertex vertex, GraphEdgeLabels edgeType) { + + ImmutablePair pair = null; + Iterator edges = vertex.edges(Direction.OUT, edgeType.getProperty()); + if (edges.hasNext()) { + // get only first edge + Edge edge = edges.next(); + pair = new ImmutablePair<>((JanusGraphVertex) edge.inVertex(), edge); + } + return pair; + } + + public Either>, JanusGraphOperationStatus> getParentNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + + List> immutablePairs = new ArrayList<>(); + + T data = null; + GraphEdge graphEdge = null; + + Either graphRes = janusGraphClient.getGraph(); + if (graphRes.isRight()) { + log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); + return Either.right(graphRes.right().value()); + } + + JanusGraph janusGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = janusGraph.query().has(key, uniqueId).vertices(); + if (vertices == null || !vertices.iterator().hasNext()) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } + + Vertex rootVertex = vertices.iterator().next(); + + Iterator edgesCreatorIterator = rootVertex.edges(Direction.IN, edgeType.name()); + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + Map edgeProps = getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + + Vertex outgoingVertex = edge.outVertex(); + Map properties = getProperties(outgoingVertex); + data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); + + ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); + immutablePairs.add(immutablePair); + } + } + + if (immutablePairs.isEmpty()) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(immutablePairs); + + } + + public Either, JanusGraphOperationStatus> getParentNode(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + + Either>, JanusGraphOperationStatus> parentNodesRes = this.getParentNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); + + if (parentNodesRes.isRight()) { + log.debug("failed to get edge key:{} uniqueId:{} edgeType {} nodeTypeEnum: {}, reason:{}", key, uniqueId, edgeType, nodeTypeEnum, parentNodesRes.right().value()); + return Either.right(parentNodesRes.right().value()); + } + + List> value = parentNodesRes.left().value(); + + if (value.size() > 1) { + return Either.right(JanusGraphOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE); + } + + return Either.left(value.get(0)); + } + + public Either, JanusGraphOperationStatus> getChildByEdgeCriteria(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, Map edgeProperties) { + + Either outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(key, uniqueId, edgeType, edgeProperties); + if (outgoingEdgeByCriteria.isRight()) { + JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value(); + log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}" + uniqueId, edgeType, edgeProperties); + return Either.right(status); + } + + Edge edge = outgoingEdgeByCriteria.left().value(); + Map edgeProps = getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + + Vertex outgoingVertex = edge.inVertex(); + Map properties = getProperties(outgoingVertex); + T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); + + ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); + + return Either.left(immutablePair); + } + + public Either, JanusGraphOperationStatus> getChildByEdgeCriteria(JanusGraphVertex vertex, GraphEdgeLabels edgeType, Map edgeProperties) { + + Either outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(vertex, edgeType, edgeProperties); + if (outgoingEdgeByCriteria.isRight()) { + JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value(); + log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertex, edgeType, edgeProperties); + return Either.right(status); + } + Edge edge = outgoingEdgeByCriteria.left().value(); + + JanusGraphVertex outgoingVertex = (JanusGraphVertex) edge.inVertex(); + + ImmutablePair immutablePair = new ImmutablePair<>(outgoingVertex, edge); + + return Either.left(immutablePair); + } + + public Either getOutgoingEdgeByCriteria(String key, String value, GraphEdgeLabels label, Map props) { + + Either vertexFrom = getVertexByProperty(key, value); + if (vertexFrom.isRight()) { + JanusGraphOperationStatus status = vertexFrom.right().value(); + if (status == JanusGraphOperationStatus.NOT_FOUND) { + return Either.right(JanusGraphOperationStatus.INVALID_ID); + } + return Either.right(status); + } + + return getOutgoingEdgeByCriteria(vertexFrom.left().value(), label, props); + } + + public Either getOutgoingEdgeByCriteria(JanusGraphVertex vertex, GraphEdgeLabels label, Map props) { + + JanusGraphVertexQuery query = vertex.query(); + query = query.direction(Direction.OUT).labels(label.getProperty()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + Edge matchingEdge = null; + Iterable edges = query.edges(); + if (edges == null) { + log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + Iterator eIter = edges.iterator(); + if (eIter.hasNext()) { + matchingEdge = eIter.next(); + } + + if (matchingEdge == null) { + log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + return Either.left(matchingEdge); + } + + public Either>, JanusGraphOperationStatus> deleteChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { + + List> result = new ArrayList<>(); + + Either>, JanusGraphOperationStatus> childrenNodesRes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); + + if (childrenNodesRes.isRight()) { + JanusGraphOperationStatus status = childrenNodesRes.right().value(); + return Either.right(status); + } + + List> list = childrenNodesRes.left().value(); + for (ImmutablePair pair : list) { + T node = pair.getKey(); + Either deleteNodeRes = this.deleteNode(node, clazz); + if (deleteNodeRes.isRight()) { + JanusGraphOperationStatus status = deleteNodeRes.right().value(); + log.error("Failed to delete node {} . status is {}", node, status); + return Either.right(status); + } + ImmutablePair deletedPair = new ImmutablePair<>(node, pair.getValue()); + result.add(deletedPair); + } + + return Either.left(result); + + } + + public void setProperties(Element element, Map properties) { + + if (properties != null && !properties.isEmpty()) { + + Object[] propertyKeyValues = new Object[properties.size() * 2]; + int i = 0; + for (Entry entry : properties.entrySet()) { + propertyKeyValues[i++] = entry.getKey(); + propertyKeyValues[i++] = entry.getValue(); + } + + ElementHelper.attachProperties(element, propertyKeyValues); + + } + + } + + public Map getProperties(Element element) { + + Map result = new HashMap<>(); + + if (element != null && element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } + + public Object getProperty(JanusGraphVertex vertex, String key) { + PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key); + return vertex.valueOrNull(propertyKey); + } + + public Object getProperty(Edge edge, String key) { + Object value = null; + Property property = edge.property(key); + if (property != null) { + return property.orElse(null); + } + return value; + } + + public Either>, JanusGraphOperationStatus> getChildrenByEdgeCriteria(Vertex vertex, String vertexUniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, + Map edgeProperties) { + + List> result = new ArrayList<>(); + + Either, JanusGraphOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgesByCriteria(vertex, edgeType, edgeProperties); + if (outgoingEdgeByCriteria.isRight()) { + JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value(); + log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertexUniqueId, edgeType, edgeProperties); + return Either.right(status); + } + + List edges = outgoingEdgeByCriteria.left().value(); + if (edges != null) { + for (Edge edge : edges) { + Map edgeProps = getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + + Vertex outgoingVertex = edge.inVertex(); + Map properties = getProperties(outgoingVertex); + T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); + + ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); + result.add(immutablePair); + } + } + + return Either.left(result); + } + + public Either, JanusGraphOperationStatus> getOutgoingEdgesByCriteria(Vertex vertexFrom, GraphEdgeLabels label, Map props) { + + List edgesResult = new ArrayList<>(); + + JanusGraphVertex janusGraphVertex = (JanusGraphVertex) vertexFrom; + JanusGraphVertexQuery query = janusGraphVertex.query(); + + query = query.direction(Direction.OUT).labels(label.getProperty()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + + Iterable edges = query.edges(); + Iterator eIter = edges.iterator(); + if (edges == null || !eIter.hasNext()) { + log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + while (eIter.hasNext()) { + Edge edge = eIter.next(); + edgesResult.add(edge); + } + + if (edgesResult.isEmpty()) { + log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props); + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + return Either.left(edgesResult); + + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphOperationStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphOperationStatus.java new file mode 100644 index 0000000000..a4ebcf79e0 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphOperationStatus.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao.janusgraph; + +public enum JanusGraphOperationStatus { + OK, NOT_CONNECTED, NOT_CREATED, INDEX_CANNOT_BE_CHANGED, NOT_FOUND, MISSING_UNIQUE_ID, MISSING_NODE_LABEL, MULTIPLE_EDGES_WITH_SAME_LABEL, CANNOT_DELETE_NON_LEAF_NODE, MULTIPLE_NODES_WITH_SAME_ID, GRAPH_IS_NOT_AVAILABLE, JANUSGRAPH_CONFIGURATION, JANUSGRAPH_SCHEMA_VIOLATION, INVALID_ELEMENT, INVALID_QUERY, INVALID_ID, RESOURCE_UNAVAILABLE, ILLEGAL_ARGUMENT, ALREADY_LOCKED, ALREADY_EXIST, MULTIPLE_CHILDS_WITH_SAME_EDGE, GENERAL_ERROR, MATCH_NOT_FOUND, INVALID_TYPE, PROPERTY_NAME_ALREADY_EXISTS, INVALID_PROPERTY, + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphUtils.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphUtils.java new file mode 100644 index 0000000000..fd9856b373 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphUtils.java @@ -0,0 +1,27 @@ +package org.openecomp.sdc.be.dao.janusgraph; + +import org.janusgraph.graphdb.query.JanusGraphPredicate; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import static org.janusgraph.core.attribute.Contain.NOT_IN; +import static java.util.Collections.emptyMap; +import static org.apache.commons.collections.CollectionUtils.isEmpty; + +public class JanusGraphUtils { + + private JanusGraphUtils() { + } + + public static Map> buildNotInPredicate(String propKey, Collection notInCollection) { + if (isEmpty(notInCollection)) { + return emptyMap(); + } + Map> predicateCriteria = new HashMap<>(); + predicateCriteria.put(propKey, new HashMap.SimpleEntry<>(NOT_IN, notInCollection)); + return predicateCriteria; + } +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/QueryType.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/QueryType.java new file mode 100644 index 0000000000..fc2f2d0643 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/QueryType.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao.janusgraph; + +/** + * Created by mlando on 9/21/2016. + */ +public enum QueryType { + HAS, HAS_NOT +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/transactions/SimpleJanusGraphTransactionManager.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/transactions/SimpleJanusGraphTransactionManager.java new file mode 100644 index 0000000000..8c67254da8 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/transactions/SimpleJanusGraphTransactionManager.java @@ -0,0 +1,70 @@ +package org.openecomp.sdc.be.dao.janusgraph.transactions; + +import org.janusgraph.core.JanusGraphException; +import org.janusgraph.core.JanusGraph; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.stereotype.Component; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.TransactionSystemException; +import org.springframework.transaction.support.SimpleTransactionStatus; + +import javax.annotation.PostConstruct; + +/** + * Simple transaction manager for the janusgraph database. + * This manager does not deal with transactions propagation and relies on the fact that transactions are automatically created with the first operation on the graph + */ +@Component +public class SimpleJanusGraphTransactionManager implements PlatformTransactionManager { + + private static final Logger log = Logger.getLogger(SimpleJanusGraphTransactionManager.class.getName()); + private final JanusGraphClient janusGraphClient; + private JanusGraph janusGraph; + + public SimpleJanusGraphTransactionManager(JanusGraphClient janusGraphClient) { + this.janusGraphClient = janusGraphClient; + } + + @PostConstruct + public void onInit() { + janusGraph = janusGraphClient.getGraph().left().on(this::onFailingToStartJanusGraph); + } + + @Override + public TransactionStatus getTransaction(TransactionDefinition transactionDefinition) { + log.debug("#getTransaction - returning simple transaction status"); + return new SimpleTransactionStatus(); + } + + @Override + public void commit(TransactionStatus transactionStatus) { + log.debug("#commit - committing transaction"); + try { + janusGraph.tx().commit(); + } catch (JanusGraphException e) { + log.debug("#commit - failed to commit transaction", e); + throw new TransactionSystemException("failed to commit transaction", e); + } + } + + @Override + public void rollback(TransactionStatus transactionStatus) { + log.debug("#rollback - committing transaction"); + try { + janusGraph.tx().rollback(); + } catch (JanusGraphException e) { + log.debug("#rollback - failed to rollback transaction", e); + throw new TransactionSystemException("failed to rollback transaction", e); + } + } + + private JanusGraph onFailingToStartJanusGraph(JanusGraphOperationStatus err) { + log.debug("#onFailingToStartJanusGraph - could not open janusgraph client"); + throw new IllegalStateException("janusgraph could not be initialized: " + err); + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java index 74852944d0..2db22a72b0 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java @@ -20,7 +20,7 @@ package org.openecomp.sdc.be.dao.jsongraph; -import com.thinkaurelius.titan.core.TitanVertex; +import org.janusgraph.core.JanusGraphVertex; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; @@ -37,7 +37,7 @@ import java.util.Map.Entry; public class GraphVertex { private String uniqueId; - private TitanVertex vertex; + private JanusGraphVertex vertex; private VertexTypeEnum label; private Map json; @@ -70,11 +70,11 @@ public class GraphVertex { this.json = json; } - public TitanVertex getVertex() { + public JanusGraphVertex getVertex() { return vertex; } - public void setVertex(TitanVertex vertex) { + public void setVertex(JanusGraphVertex vertex) { this.vertex = vertex; } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingJanusGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingJanusGraphDao.java new file mode 100644 index 0000000000..c2ef659c65 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingJanusGraphDao.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.janusgraph.JanusGraphClient; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("janusgraph-dao") +public class HealingJanusGraphDao extends JanusGraphDao { + + + @Autowired + private HealingPipelineDao healingPipelineDao; + + + public HealingJanusGraphDao(JanusGraphClient janusGraphClient) { + super(janusGraphClient); + } + + @Override + public Either, JanusGraphOperationStatus> getChildrenVertecies(GraphVertex parentVertex, + EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, JanusGraphOperationStatus> 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/HealingTitanDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java deleted file mode 100644 index fb6b9d8fa3..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/HealingTitanDao.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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/JanusGraphDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/JanusGraphDao.java new file mode 100644 index 0000000000..5917b14fd3 --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/JanusGraphDao.java @@ -0,0 +1,1077 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.dao.jsongraph; + +import org.janusgraph.core.*; +import fj.data.Either; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.*; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; +import org.openecomp.sdc.common.jsongraph.util.CommonUtility; +import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.io.IOException; +import java.util.*; +import java.util.Map.Entry; + +import static org.apache.commons.collections.CollectionUtils.isEmpty; + + +public class JanusGraphDao { + JanusGraphClient janusGraphClient; + + private static Logger logger = Logger.getLogger(JanusGraphDao.class.getName()); + + public JanusGraphDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) { + this.janusGraphClient = janusGraphClient; + logger.info("** JanusGraphDao created"); + } + + public JanusGraphOperationStatus commit() { + logger.debug("#commit - The operation succeeded. Doing commit..."); + return janusGraphClient.commit(); + } + + public JanusGraphOperationStatus rollback() { + logger.debug("#rollback - The operation failed. Doing rollback..."); + return janusGraphClient.rollback(); + } + + public Either getGraph() { + return janusGraphClient.getGraph(); + } + + /** + * + * @param graphVertex + * @return + */ + public Either createVertex(GraphVertex graphVertex) { + logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId()); + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphVertex vertex = tGraph.addVertex(); + + setVertexProperties(vertex, graphVertex); + + graphVertex.setVertex(vertex); + + return Either.left(graphVertex); + + } catch (Exception e) { + logger.debug("Failed to create Node for ID [{}]", graphVertex.getUniqueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + logger.debug("Failed to create vertex for ID [{}] {}", graphVertex.getUniqueId(), graph.right().value()); + return Either.right(graph.right().value()); + } + } + + /** + * + * @param name + * @param value + * @param label + * @return + */ + public Either getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) { + return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll); + } + + public Either getVertexByLabel(VertexTypeEnum label) { + return janusGraphClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices()).left().bind(janusGraphVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, janusGraphVertices)); + } + + private Either getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable vertices) { + Iterator iterator = vertices.iterator(); + if (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + GraphVertex graphVertex = createAndFill(vertex, parseFlag); + + return Either.left(graphVertex); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + /** + * + * @param name + * @param value + * @param label + * @param parseFlag + * @return + */ + public Either getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) { + + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices(); + + java.util.Iterator iterator = vertecies.iterator(); + if (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + GraphVertex graphVertex = createAndFill(vertex, parseFlag); + + return Either.left(graphVertex); + } + if (logger.isDebugEnabled()) { + logger.debug("No vertex in graph for key = {} and value = {} label = {}" + name, value, label); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (logger.isDebugEnabled()) { + logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + /** + * + * @param id + * @return + */ + public Either getVertexById(String id) { + return getVertexById(id, JsonParseFlagEnum.ParseAll); + } + + /** + * + * @param id + * @param parseFlag + * @return + */ + public Either getVertexById(String id, JsonParseFlagEnum parseFlag) { + + Either graph = janusGraphClient.getGraph(); + if (id == null) { + if (logger.isDebugEnabled()) { + logger.debug("No vertex in graph for id = {} ", id); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices(); + + java.util.Iterator iterator = vertecies.iterator(); + if (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + GraphVertex graphVertex = createAndFill(vertex, parseFlag); + return Either.left(graphVertex); + } else { + if (logger.isDebugEnabled()) { + logger.debug("No vertex in graph for id = {}", id); + } + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to get vertex in graph for id {} ", id); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + private void setVertexProperties(JanusGraphVertex vertex, GraphVertex graphVertex) throws IOException { + + if (graphVertex.getMetadataProperties() != null) { + for (Map.Entry entry : graphVertex.getMetadataProperties().entrySet()) { + if (entry.getValue() != null) { + vertex.property(entry.getKey().getProperty(), entry.getValue()); + } + } + } + vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName()); + + Map json = graphVertex.getJson(); + if (json != null) { + String jsonStr = JsonParserUtils.toJson(json); + vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr); + + } + Map jsonMetadata = graphVertex.getMetadataJson(); + if (jsonMetadata != null) { + String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata); + vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr); + } + } + + public void setVertexProperties(Vertex vertex, Map properties) { + for (Map.Entry entry : properties.entrySet()) { + if (entry.getValue() != null) { + vertex.property(entry.getKey(), entry.getValue()); + } + } + } + + private GraphVertex createAndFill(JanusGraphVertex vertex, JsonParseFlagEnum parseFlag) { + GraphVertex graphVertex = new GraphVertex(); + graphVertex.setVertex(vertex); + parseVertexProperties(graphVertex, parseFlag); + return graphVertex; + } + + public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) { + JanusGraphVertex vertex = graphVertex.getVertex(); + Map properties = getVertexProperties(vertex); + VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL))); + for (Map.Entry entry : properties.entrySet()) { + GraphPropertyEnum key = entry.getKey(); + switch (key) { + case UNIQUE_ID: + graphVertex.setUniqueId((String) entry.getValue()); + break; + case LABEL: + graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue())); + break; + case COMPONENT_TYPE: + String type = (String) entry.getValue(); + if (type != null) { + graphVertex.setType(ComponentTypeEnum.valueOf(type)); + } + break; + case JSON: + if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) { + String json = (String) entry.getValue(); + Map jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson()); + graphVertex.setJson(jsonObj); + } + break; + case METADATA: + if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) { + String json = (String) entry.getValue(); + Map metadatObj = JsonParserUtils.toMap(json); + graphVertex.setMetadataJson(metadatObj); + } + break; + default: + graphVertex.addMetadataProperty(key, entry.getValue()); + break; + } + } + } + + public JanusGraphOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map properties) { + return createEdge(from.getVertex(), to.getVertex(), label, properties); + } + + public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map properties) { + if (logger.isTraceEnabled()) { + logger.trace("Try to connect {} with {} label {} properties {}", + from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), + to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties); + } + if (from == null || to == null) { + logger.trace("No JanusGraph vertex for id from {} or id to {}", + from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), + to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty())); + return JanusGraphOperationStatus.NOT_FOUND; + } + Edge edge = from.addEdge(label.name(), to); + JanusGraphOperationStatus status; + try { + setEdgeProperties(edge, properties); + status = JanusGraphOperationStatus.OK; + } catch (IOException e) { + logger.debug("Failed to set properties on edge properties [{}]", properties, e); + status = JanusGraphOperationStatus.GENERAL_ERROR; + } + return status; + } + + public Map getVertexProperties(Element element) { + + Map result = new HashMap<>(); + + if (element != null && element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key); + if (valueOf != null) { + result.put(valueOf, value); + } + } + } + return result; + } + + public Map getEdgeProperties(Element element) { + + Map result = new HashMap<>(); + + if (element != null && element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key); + if (valueOf != null) { + if (valueOf == EdgePropertyEnum.INSTANCES) { + List list = JsonParserUtils.toList((String) value, String.class); + result.put(valueOf, list); + } else { + result.put(valueOf, value); + } + } + } + } + return result; + } + + public void setEdgeProperties(Element element, Map properties) throws IOException { + + if (properties != null && !properties.isEmpty()) { + + Object[] propertyKeyValues = new Object[properties.size() * 2]; + int i = 0; + for (Entry entry : properties.entrySet()) { + propertyKeyValues[i++] = entry.getKey().getProperty(); + Object value = entry.getValue(); + if (entry.getKey() == EdgePropertyEnum.INSTANCES) { + String jsonStr = JsonParserUtils.toJson(value); + propertyKeyValues[i++] = jsonStr; + } else { + propertyKeyValues[i++] = entry.getValue(); + } + } + ElementHelper.attachProperties(element, propertyKeyValues); + } + } + + public Either, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map props) { + return getByCriteria(type, props, JsonParseFlagEnum.ParseAll); + } + + public Either, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map props, JsonParseFlagEnum parseFlag) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + if (type != null) { + query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName()); + } + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey().getProperty(), entry.getValue()); + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + + Map newProp = getVertexProperties(vertex); + GraphVertex graphVertex = createAndFill(vertex, parseFlag); + + result.add(graphVertex); + } + if (logger.isDebugEnabled()) { + logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(result); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map props, Map hasNotProps, JsonParseFlagEnum parseFlag) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + JanusGraphQuery query = tGraph.query(); + if (type != null) { + query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName()); + } + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.has(entry.getKey().getProperty(), entry.getValue()); + } + } + if (hasNotProps != null && !hasNotProps.isEmpty()) { + for (Map.Entry entry : hasNotProps.entrySet()) { + if (entry.getValue() instanceof List) { + buildMultipleNegateQueryFromList(entry, query); + } else { + query = query.hasNot(entry.getKey().getProperty(), entry.getValue()); + } + } + } + Iterable vertices = query.vertices(); + if (vertices == null) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList<>(); + + while (iterator.hasNext()) { + JanusGraphVertex vertex = iterator.next(); + + Map newProp = getVertexProperties(vertex); + GraphVertex graphVertex = createAndFill(vertex, parseFlag); + + result.add(graphVertex); + } + if (logger.isDebugEnabled()) { + logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); + } + if (result.size() == 0) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + + return Either.left(result); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + public Either, JanusGraphOperationStatus> getCatalogOrArchiveVerticies(boolean isCatalog) { + Either graph = janusGraphClient.getGraph(); + if (graph.isLeft()) { + try { + JanusGraph tGraph = graph.left().value(); + + String name = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName(); + Iterable vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), name).vertices(); + if (vCatalogIter == null) { + logger.debug("Failed to fetch catalog vertex"); + return Either.right(JanusGraphOperationStatus.GENERAL_ERROR); + } + JanusGraphVertex catalogV = vCatalogIter.iterator().next(); + if (catalogV == null) { + logger.debug("Failed to fetch catalog vertex"); + return Either.right(JanusGraphOperationStatus.GENERAL_ERROR); + } + String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name(); + Iterator vertices = catalogV.vertices(Direction.OUT, edgeLabel); + + return Either.left(vertices); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria: ", e); + } + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + } else { + if (logger.isDebugEnabled()) { + logger.debug("Failed get by criteria : ", graph.right().value()); + } + return Either.right(graph.right().value()); + } + } + + private void buildMultipleNegateQueryFromList(Map.Entry entry, JanusGraphQuery query) { + List negateList = (List) entry.getValue(); + for (Object listItem : negateList) { + query.hasNot(entry.getKey().getProperty(), listItem); + } + } + + /** + * + * @param parentVertex + * @param edgeLabel + * @param parseFlag + * @return + */ + public Either getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, JanusGraphOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag); + if (childrenVertecies.isRight()) { + return Either.right(childrenVertecies.right().value()); + } + return Either.left(childrenVertecies.left().value().get(0)); + } + + /** + * + * @param parentVertex + * @param edgeLabel + * @param parseFlag + * @return + */ + public Either getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, JanusGraphOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag); + if (childrenVertecies.isRight()) { + return Either.right(childrenVertecies.right().value()); + } + return Either.left(childrenVertecies.left().value().get(0)); + } + + public Either getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, JanusGraphOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag); + if (childrenVertecies.isRight()) { + return Either.right(childrenVertecies.right().value()); + } + if (isEmpty(childrenVertecies.left().value())){ + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + return Either.left(childrenVertecies.left().value().get(0)); + } + + public Either getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + Either, JanusGraphOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag); + if (childrenVertecies.isRight() ) { + return Either.right(childrenVertecies.right().value()); + } + if (isEmpty(childrenVertecies.left().value())){ + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + return Either.left(childrenVertecies.left().value().get(0)); + } + + /** + * + * @param parentVertex + * @param edgeLabel + * @param parseFlag + * @return + */ + public Either, JanusGraphOperationStatus> getChildrenVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT); + } + + public Either, JanusGraphOperationStatus> getParentVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN); + } + + public Either, JanusGraphOperationStatus> getParentVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN); + } + + private Either, JanusGraphOperationStatus> getAdjacentVerticies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) { + List list = new ArrayList<>(); + try { + Either graphRes = janusGraphClient.getGraph(); + if (graphRes.isRight()) { + logger.error("Failed to retrieve graph. status is {}", graphRes); + return Either.right(graphRes.right().value()); + } + Iterator edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name()); + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + JanusGraphVertex vertex; + if (direction == Direction.IN) { + vertex = (JanusGraphVertex) edge.outVertex(); + } else { + vertex = (JanusGraphVertex) edge.inVertex(); + } + // GraphVertex graphVertex = createAndFill(vertex, parseFlag); + + list.add(vertex); + } + } + if (list.isEmpty()) { + return Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } catch (Exception e) { + logger.error("Failed to perform graph operation ", e); + Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + + return Either.left(list); + } + + /** + * + * @param parentVertex + * @param edgeLabel + * @param parseFlag + * @return + */ + public Either, JanusGraphOperationStatus> getChildrenVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { + return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT); + } + + private Either, JanusGraphOperationStatus> getAdjacentVerticies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) { + List list = new ArrayList<>(); + + Either, JanusGraphOperationStatus> adjacentVerticies = getAdjacentVerticies(parentVertex.getVertex(), edgeLabel, parseFlag, direction); + if (adjacentVerticies.isRight()) { + return Either.right(adjacentVerticies.right().value()); + } + adjacentVerticies.left().value().stream().forEach(vertex -> { + list.add(createAndFill((JanusGraphVertex) vertex, parseFlag)); + }); + + return Either.left(list); + } + + /** + * Searches Edge by received label and criteria + * + * @param vertex + * @param label + * @param properties + * @return found edge or JanusGraphOperationStatus + */ + public Either getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map properties) { + + Either result = null; + Edge matchingEdge = null; + String notFoundMsg = "No edges in graph for criteria"; + try { + JanusGraphVertexQuery query = vertex.getVertex().query().labels(label.name()); + + if (properties != null && !properties.isEmpty()) { + for (Map.Entry entry : properties.entrySet()) { + query = query.has(entry.getKey().getProperty(), entry.getValue()); + } + } + + Iterable edges = query.edges(); + if (edges == null) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); + result = Either.right(JanusGraphOperationStatus.NOT_FOUND); + } else { + Iterator eIter = edges.iterator(); + if (eIter.hasNext()) { + matchingEdge = eIter.next(); + } else { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); + result = Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } + if (result == null) { + result = Either.left(matchingEdge); + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + return result; + } + + public Either getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label, Map properties) { + Either result = null; + Edge matchingEdge = null; + String notFoundMsg = "No edges in graph for criteria"; + try { + + Iterator edges = vertex.getVertex().edges(Direction.OUT, label.name()); + while (edges.hasNext()) { + matchingEdge = edges.next(); + Vertex childV = matchingEdge.inVertex(); + Map vertexProperties = getVertexProperties(childV); + Optional> findNotMatch = properties.entrySet().stream().filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst(); + if (!findNotMatch.isPresent()) { + result = Either.left(matchingEdge); + } + } + if (result == null) { + //no match + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); + result = Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + return result; + } + + /** + * Deletes Edge by received label and criteria + * + * @param vertex + * @param label + * @param properties + * @return + */ + public Either deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map properties) { + Either result = null; + try { + result = getBelongingEdgeByCriteria(vertex, label, properties); + if (result.isLeft()) { + Edge edge = result.left().value(); + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId()); + edge.remove(); + result = Either.left(edge); + } else { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId()); + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex == null ? "NULL" : vertex.getUniqueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + return result; + } + + @SuppressWarnings("unchecked") + /** + * Deletes an edge between vertices fromVertex and toVertex according to received label + * + * @param fromVertex + * @param toVertex + * @param label + * @return + */ + + public Either deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) { + return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false); + } + + public Either deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) { + return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true); + } + + public Either deleteEdge(JanusGraphVertex fromVertex, JanusGraphVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) { + Either result = null; + try { + Iterable edges = fromVertex.query().labels(label.name()).edges(); + Iterator eIter = edges.iterator(); + while (eIter.hasNext()) { + Edge edge = eIter.next(); + String currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty()); + if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo); + edge.remove(); + result = Either.left(edge); + if (!deleteAll) { + break; + } + } + } + if (result == null) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo); + result = Either.right(JanusGraphOperationStatus.NOT_FOUND); + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + return result; + } + + public JanusGraphOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) { + try { + Iterator edges = fromVertex.getVertex().edges(direction, label.name()); + + while (edges.hasNext()) { + Edge edge = edges.next(); + edge.remove(); + } + } catch (Exception e) { + logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e); + return JanusGraphClient.handleJanusGraphException(e); + } + return JanusGraphOperationStatus.OK; + } + + /** + * Updates vertex properties. Note that graphVertex argument should contain updated data + * + * @param graphVertex + * @return + */ + public Either updateVertex(GraphVertex graphVertex) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId()); + try { + graphVertex.updateMetadataJsonWithCurrentMetadataProperties(); + setVertexProperties(graphVertex.getVertex(), graphVertex); + + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e); + return Either.right(JanusGraphClient.handleJanusGraphException(e)); + } + return Either.left(graphVertex); + } + + /** + * Fetches vertices by uniqueId according to received parse flag + * + * @param verticesToGet + * @return + */ + public Either, JanusGraphOperationStatus> getVerticesByUniqueIdAndParseFlag(Map> verticesToGet) { + + Either, JanusGraphOperationStatus> result = null; + Map vertices = new HashMap<>(); + JanusGraphOperationStatus titatStatus; + Either getVertexRes = null; + for (Map.Entry> entry : verticesToGet.entrySet()) { + if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) { + getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue()); + } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) { + getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue()); + } + if (getVertexRes == null) { + titatStatus = JanusGraphOperationStatus.ILLEGAL_ARGUMENT; + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus); + return Either.right(titatStatus); + } + if (getVertexRes.isRight()) { + titatStatus = getVertexRes.right().value(); + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus); + result = Either.right(titatStatus); + break; + } else { + vertices.put(entry.getKey(), getVertexRes.left().value()); + } + } + if (result == null) { + result = Either.left(vertices); + } + return result; + } + + /** + * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge + * + * @param from + * @param to + * @param label + * @param edgeToCopy + * @return + */ + public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) { + return createEdge(from, to, label, getEdgeProperties(edgeToCopy)); + } + + public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex!=null ? fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL", + toVertex!=null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL"); + + JanusGraphOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge); + if (result == JanusGraphOperationStatus.OK) { + prevEdge.remove(); + } + return result; + } + + /** + * Replaces previous label of edge with new label + * + * @param fromVertex + * @param toVertex + * @param prevLabel + * @param newLabel + * @return + */ + public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) { + + JanusGraphOperationStatus result = null; + Iterator prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name()); + if (prevEdgeIter == null || !prevEdgeIter.hasNext()) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), + toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty())); + result = JanusGraphOperationStatus.NOT_FOUND; + } + if (result == null) { + result = replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel); + } + return result; + } + + /** + * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too. + * + * + * @param vertex + * @param properties + * @return + */ + public JanusGraphOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map properties) { + try { + if (!MapUtils.isEmpty(properties)) { + String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value(); + Map jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr); + for (Map.Entry property : properties.entrySet()) { + vertex.property(property.getKey().getProperty(), property.getValue()); + jsonMetadataMap.put(property.getKey().getProperty(), property.getValue()); + } + vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap)); + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage()); + return JanusGraphClient.handleJanusGraphException(e); + } + return JanusGraphOperationStatus.OK; + } + + public JanusGraphOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) { + try { + Iterator edges = vertex.getVertex().edges(direction, label.name()); + + while (edges.hasNext()) { + Edge edge = edges.next(); + Vertex secondVertex; + Direction reverseDirection; + if (direction == Direction.IN) { + secondVertex = edge.outVertex(); + reverseDirection = Direction.OUT; + } else { + secondVertex = edge.inVertex(); + reverseDirection = Direction.IN; + } + edge.remove(); + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex()); + + Iterator restOfEdges = secondVertex.edges(reverseDirection, label.name()); + if (!restOfEdges.hasNext()) { + secondVertex.remove(); + CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId()); + } + } + } catch (Exception e) { + CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e); + return JanusGraphClient.handleJanusGraphException(e); + } + return JanusGraphOperationStatus.OK; + } + + public Object getProperty(JanusGraphVertex vertex, String key) { + PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key); + return vertex.valueOrNull(propertyKey); + } + + public Object getProperty(Edge edge, EdgePropertyEnum key) { + Object value = null; + try { + Property property = edge.property(key.getProperty()); + if (property != null) { + value = property.orElse(null); + if (value != null && key == EdgePropertyEnum.INSTANCES) { + return JsonParserUtils.toList((String) value, String.class); + } + return value; + } + } catch (Exception e) { + + } + return value; + } + + /** + * + * @param vertexA + * @param vertexB + * @param label + * @param direction + * @return + */ + public JanusGraphOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) { + JanusGraphOperationStatus result = deleteEdgeByDirection(vertexA, direction, label); + if (result != JanusGraphOperationStatus.OK) { + logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result); + return result; + } + JanusGraphOperationStatus createRelation; + if (direction == Direction.IN) { + createRelation = createEdge(vertexB, vertexA, label, null); + } else { + createRelation = createEdge(vertexA, vertexB, label, null); + } + if (createRelation != JanusGraphOperationStatus.OK) { + return createRelation; + } + return JanusGraphOperationStatus.OK; + } + + public Either getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map properties) { + Either getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse); + if (getVertexRes.isRight()) { + return Either.right(getVertexRes.right().value()); + } + return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties); + } +} 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 deleted file mode 100644 index a31900acce..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/TitanDao.java +++ /dev/null @@ -1,1078 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao.jsongraph; - -import com.thinkaurelius.titan.core.*; -import fj.data.Either; -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.tinkerpop.gremlin.structure.*; -import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; -import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; -import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum; -import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; -import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; -import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils; -import org.openecomp.sdc.be.dao.titan.TitanGraphClient; -import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; -import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -import org.openecomp.sdc.common.jsongraph.util.CommonUtility; -import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import java.io.IOException; -import java.util.*; -import java.util.Map.Entry; - -import static org.apache.commons.collections.CollectionUtils.isEmpty; - - -public class TitanDao { - TitanGraphClient titanClient; - - private static Logger logger = Logger.getLogger(TitanDao.class.getName()); - - public TitanDao(@Qualifier("titan-client") TitanGraphClient titanClient) { - this.titanClient = titanClient; - logger.info("** TitanDao created"); - } - - public TitanOperationStatus commit() { - logger.debug("#commit - The operation succeeded. Doing commit..."); - return titanClient.commit(); - } - - public TitanOperationStatus rollback() { - logger.debug("#rollback - The operation failed. Doing rollback..."); - return titanClient.rollback(); - } - - public Either getGraph() { - return titanClient.getGraph(); - } - - /** - * - * @param graphVertex - * @return - */ - public Either createVertex(GraphVertex graphVertex) { - logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId()); - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanVertex vertex = tGraph.addVertex(); - - setVertexProperties(vertex, graphVertex); - - graphVertex.setVertex(vertex); - - return Either.left(graphVertex); - - } catch (Exception e) { - logger.debug("Failed to create Node for ID [{}]", graphVertex.getUniqueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - logger.debug("Failed to create vertex for ID [{}] {}", graphVertex.getUniqueId(), graph.right().value()); - return Either.right(graph.right().value()); - } - } - - /** - * - * @param name - * @param value - * @param label - * @return - */ - public Either getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) { - return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll); - } - - public Either getVertexByLabel(VertexTypeEnum label) { - return titanClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices()).left().bind(titanVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, titanVertices)); - } - - private Either getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable vertices) { - Iterator iterator = vertices.iterator(); - if (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - GraphVertex graphVertex = createAndFill(vertex, parseFlag); - - return Either.left(graphVertex); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - /** - * - * @param name - * @param value - * @param label - * @param parseFlag - * @return - */ - public Either getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) { - - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - @SuppressWarnings("unchecked") - Iterable vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices(); - - java.util.Iterator iterator = vertecies.iterator(); - if (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - GraphVertex graphVertex = createAndFill(vertex, parseFlag); - - return Either.left(graphVertex); - } - if (logger.isDebugEnabled()) { - logger.debug("No vertex in graph for key = {} and value = {} label = {}" + name, value, label); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (logger.isDebugEnabled()) { - logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - /** - * - * @param id - * @return - */ - public Either getVertexById(String id) { - return getVertexById(id, JsonParseFlagEnum.ParseAll); - } - - /** - * - * @param id - * @param parseFlag - * @return - */ - public Either getVertexById(String id, JsonParseFlagEnum parseFlag) { - - Either graph = titanClient.getGraph(); - if (id == null) { - if (logger.isDebugEnabled()) { - logger.debug("No vertex in graph for id = {} ", id); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - @SuppressWarnings("unchecked") - Iterable vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices(); - - java.util.Iterator iterator = vertecies.iterator(); - if (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - GraphVertex graphVertex = createAndFill(vertex, parseFlag); - return Either.left(graphVertex); - } else { - if (logger.isDebugEnabled()) { - logger.debug("No vertex in graph for id = {}", id); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed to get vertex in graph for id {} ", id); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - private void setVertexProperties(TitanVertex vertex, GraphVertex graphVertex) throws IOException { - - if (graphVertex.getMetadataProperties() != null) { - for (Map.Entry entry : graphVertex.getMetadataProperties().entrySet()) { - if (entry.getValue() != null) { - vertex.property(entry.getKey().getProperty(), entry.getValue()); - } - } - } - vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName()); - - Map json = graphVertex.getJson(); - if (json != null) { - String jsonStr = JsonParserUtils.toJson(json); - vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr); - - } - Map jsonMetadata = graphVertex.getMetadataJson(); - if (jsonMetadata != null) { - String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata); - vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr); - } - } - - public void setVertexProperties(Vertex vertex, Map properties) { - for (Map.Entry entry : properties.entrySet()) { - if (entry.getValue() != null) { - vertex.property(entry.getKey(), entry.getValue()); - } - } - } - - private GraphVertex createAndFill(TitanVertex vertex, JsonParseFlagEnum parseFlag) { - GraphVertex graphVertex = new GraphVertex(); - graphVertex.setVertex(vertex); - parseVertexProperties(graphVertex, parseFlag); - return graphVertex; - } - - public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) { - TitanVertex vertex = graphVertex.getVertex(); - Map properties = getVertexProperties(vertex); - VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL))); - for (Map.Entry entry : properties.entrySet()) { - GraphPropertyEnum key = entry.getKey(); - switch (key) { - case UNIQUE_ID: - graphVertex.setUniqueId((String) entry.getValue()); - break; - case LABEL: - graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue())); - break; - case COMPONENT_TYPE: - String type = (String) entry.getValue(); - if (type != null) { - graphVertex.setType(ComponentTypeEnum.valueOf(type)); - } - break; - case JSON: - if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) { - String json = (String) entry.getValue(); - Map jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson()); - graphVertex.setJson(jsonObj); - } - break; - case METADATA: - if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) { - String json = (String) entry.getValue(); - Map metadatObj = JsonParserUtils.toMap(json); - graphVertex.setMetadataJson(metadatObj); - } - break; - default: - graphVertex.addMetadataProperty(key, entry.getValue()); - break; - } - } - } - - public TitanOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map properties) { - return createEdge(from.getVertex(), to.getVertex(), label, properties); - } - - public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map properties) { - if (logger.isTraceEnabled()) { - logger.trace("Try to connect {} with {} label {} properties {}", - from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), - to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties); - } - if (from == null || to == null) { - logger.trace("No Titan vertex for id from {} or id to {}", - from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), - to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty())); - return TitanOperationStatus.NOT_FOUND; - } - Edge edge = from.addEdge(label.name(), to); - TitanOperationStatus status; - try { - setEdgeProperties(edge, properties); - status = TitanOperationStatus.OK; - } catch (IOException e) { - logger.debug("Failed to set properties on edge properties [{}]", properties, e); - status = TitanOperationStatus.GENERAL_ERROR; - } - return status; - } - - public Map getVertexProperties(Element element) { - - Map result = new HashMap<>(); - - if (element != null && element.keys() != null && element.keys().size() > 0) { - Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); - - for (Entry entry : propertyMap.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue().value(); - - GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key); - if (valueOf != null) { - result.put(valueOf, value); - } - } - } - return result; - } - - public Map getEdgeProperties(Element element) { - - Map result = new HashMap<>(); - - if (element != null && element.keys() != null && element.keys().size() > 0) { - Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); - - for (Entry entry : propertyMap.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue().value(); - - EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key); - if (valueOf != null) { - if (valueOf == EdgePropertyEnum.INSTANCES) { - List list = JsonParserUtils.toList((String) value, String.class); - result.put(valueOf, list); - } else { - result.put(valueOf, value); - } - } - } - } - return result; - } - - public void setEdgeProperties(Element element, Map properties) throws IOException { - - if (properties != null && !properties.isEmpty()) { - - Object[] propertyKeyValues = new Object[properties.size() * 2]; - int i = 0; - for (Entry entry : properties.entrySet()) { - propertyKeyValues[i++] = entry.getKey().getProperty(); - Object value = entry.getValue(); - if (entry.getKey() == EdgePropertyEnum.INSTANCES) { - String jsonStr = JsonParserUtils.toJson(value); - propertyKeyValues[i++] = jsonStr; - } else { - propertyKeyValues[i++] = entry.getValue(); - } - } - ElementHelper.attachProperties(element, propertyKeyValues); - } - } - - public Either, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map props) { - return getByCriteria(type, props, JsonParseFlagEnum.ParseAll); - } - - public Either, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map props, JsonParseFlagEnum parseFlag) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - if (type != null) { - query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName()); - } - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey().getProperty(), entry.getValue()); - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - - Map newProp = getVertexProperties(vertex); - GraphVertex graphVertex = createAndFill(vertex, parseFlag); - - result.add(graphVertex); - } - if (logger.isDebugEnabled()) { - logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(result); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map props, Map hasNotProps, JsonParseFlagEnum parseFlag) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - if (type != null) { - query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName()); - } - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey().getProperty(), entry.getValue()); - } - } - if (hasNotProps != null && !hasNotProps.isEmpty()) { - for (Map.Entry entry : hasNotProps.entrySet()) { - if (entry.getValue() instanceof List) { - buildMultipleNegateQueryFromList(entry, query); - } else { - query = query.hasNot(entry.getKey().getProperty(), entry.getValue()); - } - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - - Map newProp = getVertexProperties(vertex); - GraphVertex graphVertex = createAndFill(vertex, parseFlag); - - result.add(graphVertex); - } - if (logger.isDebugEnabled()) { - logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(result); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getCatalogOrArchiveVerticies(boolean isCatalog) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - String name = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName(); - Iterable vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), name).vertices(); - if (vCatalogIter == null) { - logger.debug("Failed to fetch catalog vertex"); - return Either.right(TitanOperationStatus.GENERAL_ERROR); - } - TitanVertex catalogV = vCatalogIter.iterator().next(); - if (catalogV == null) { - logger.debug("Failed to fetch catalog vertex"); - return Either.right(TitanOperationStatus.GENERAL_ERROR); - } - String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name(); - Iterator vertices = catalogV.vertices(Direction.OUT, edgeLabel); - - return Either.left(vertices); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria: ", e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (logger.isDebugEnabled()) { - logger.debug("Failed get by criteria : ", graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - private void buildMultipleNegateQueryFromList(Map.Entry entry, TitanGraphQuery query) { - List negateList = (List) entry.getValue(); - for (Object listItem : negateList) { - query.hasNot(entry.getKey().getProperty(), listItem); - } - } - - /** - * - * @param parentVertex - * @param edgeLabel - * @param parseFlag - * @return - */ - public Either getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - Either, TitanOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag); - if (childrenVertecies.isRight()) { - return Either.right(childrenVertecies.right().value()); - } - return Either.left(childrenVertecies.left().value().get(0)); - } - - /** - * - * @param parentVertex - * @param edgeLabel - * @param parseFlag - * @return - */ - public Either getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - Either, TitanOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag); - if (childrenVertecies.isRight()) { - return Either.right(childrenVertecies.right().value()); - } - return Either.left(childrenVertecies.left().value().get(0)); - } - - public Either getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - Either, TitanOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag); - if (childrenVertecies.isRight()) { - return Either.right(childrenVertecies.right().value()); - } - if (isEmpty(childrenVertecies.left().value())){ - return Either.right(TitanOperationStatus.NOT_FOUND); - } - return Either.left(childrenVertecies.left().value().get(0)); - } - - public Either getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - Either, TitanOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag); - if (childrenVertecies.isRight() ) { - return Either.right(childrenVertecies.right().value()); - } - if (isEmpty(childrenVertecies.left().value())){ - return Either.right(TitanOperationStatus.NOT_FOUND); - } - return Either.left(childrenVertecies.left().value().get(0)); - } - - /** - * - * @param parentVertex - * @param edgeLabel - * @param parseFlag - * @return - */ - public Either, TitanOperationStatus> getChildrenVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT); - } - - public Either, TitanOperationStatus> getParentVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN); - } - - public Either, TitanOperationStatus> getParentVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN); - } - - private Either, TitanOperationStatus> getAdjacentVerticies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) { - List list = new ArrayList<>(); - try { - Either graphRes = titanClient.getGraph(); - if (graphRes.isRight()) { - logger.error("Failed to retrieve graph. status is {}", graphRes); - return Either.right(graphRes.right().value()); - } - Iterator edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name()); - if (edgesCreatorIterator != null) { - while (edgesCreatorIterator.hasNext()) { - Edge edge = edgesCreatorIterator.next(); - TitanVertex vertex; - if (direction == Direction.IN) { - vertex = (TitanVertex) edge.outVertex(); - } else { - vertex = (TitanVertex) edge.inVertex(); - } - // GraphVertex graphVertex = createAndFill(vertex, parseFlag); - - list.add(vertex); - } - } - if (list.isEmpty()) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - } catch (Exception e) { - logger.error("Failed to perform graph operation ", e); - Either.right(TitanGraphClient.handleTitanException(e)); - } - - return Either.left(list); - } - - /** - * - * @param parentVertex - * @param edgeLabel - * @param parseFlag - * @return - */ - public Either, TitanOperationStatus> getChildrenVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) { - return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT); - } - - private Either, TitanOperationStatus> getAdjacentVerticies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) { - List list = new ArrayList<>(); - - Either, TitanOperationStatus> adjacentVerticies = getAdjacentVerticies(parentVertex.getVertex(), edgeLabel, parseFlag, direction); - if (adjacentVerticies.isRight()) { - return Either.right(adjacentVerticies.right().value()); - } - adjacentVerticies.left().value().stream().forEach(vertex -> { - list.add(createAndFill((TitanVertex) vertex, parseFlag)); - }); - - return Either.left(list); - } - - /** - * Searches Edge by received label and criteria - * - * @param vertex - * @param label - * @param properties - * @return found edge or TitanOperationStatus - */ - public Either getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map properties) { - - Either result = null; - Edge matchingEdge = null; - String notFoundMsg = "No edges in graph for criteria"; - try { - TitanVertexQuery query = vertex.getVertex().query().labels(label.name()); - - if (properties != null && !properties.isEmpty()) { - for (Map.Entry entry : properties.entrySet()) { - query = query.has(entry.getKey().getProperty(), entry.getValue()); - } - } - - Iterable edges = query.edges(); - if (edges == null) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); - result = Either.right(TitanOperationStatus.NOT_FOUND); - } else { - Iterator eIter = edges.iterator(); - if (eIter.hasNext()) { - matchingEdge = eIter.next(); - } else { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); - result = Either.right(TitanOperationStatus.NOT_FOUND); - } - } - if (result == null) { - result = Either.left(matchingEdge); - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - return result; - } - - public Either getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label, Map properties) { - Either result = null; - Edge matchingEdge = null; - String notFoundMsg = "No edges in graph for criteria"; - try { - - Iterator edges = vertex.getVertex().edges(Direction.OUT, label.name()); - while (edges.hasNext()) { - matchingEdge = edges.next(); - Vertex childV = matchingEdge.inVertex(); - Map vertexProperties = getVertexProperties(childV); - Optional> findNotMatch = properties.entrySet().stream().filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst(); - if (!findNotMatch.isPresent()) { - result = Either.left(matchingEdge); - } - } - if (result == null) { - //no match - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg); - result = Either.right(TitanOperationStatus.NOT_FOUND); - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - return result; - } - - /** - * Deletes Edge by received label and criteria - * - * @param vertex - * @param label - * @param properties - * @return - */ - public Either deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map properties) { - Either result = null; - try { - result = getBelongingEdgeByCriteria(vertex, label, properties); - if (result.isLeft()) { - Edge edge = result.left().value(); - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId()); - edge.remove(); - result = Either.left(edge); - } else { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId()); - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex == null ? "NULL" : vertex.getUniqueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - return result; - } - - @SuppressWarnings("unchecked") - /** - * Deletes an edge between vertices fromVertex and toVertex according to received label - * - * @param fromVertex - * @param toVertex - * @param label - * @return - */ - - public Either deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) { - return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false); - } - - public Either deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) { - return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true); - } - - public Either deleteEdge(TitanVertex fromVertex, TitanVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) { - Either result = null; - try { - Iterable edges = fromVertex.query().labels(label.name()).edges(); - Iterator eIter = edges.iterator(); - while (eIter.hasNext()) { - Edge edge = eIter.next(); - String currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty()); - if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo); - edge.remove(); - result = Either.left(edge); - if (!deleteAll) { - break; - } - } - } - if (result == null) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo); - result = Either.right(TitanOperationStatus.NOT_FOUND); - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - return result; - } - - public TitanOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) { - try { - Iterator edges = fromVertex.getVertex().edges(direction, label.name()); - - while (edges.hasNext()) { - Edge edge = edges.next(); - edge.remove(); - } - } catch (Exception e) { - logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e); - return TitanGraphClient.handleTitanException(e); - } - return TitanOperationStatus.OK; - } - - /** - * Updates vertex properties. Note that graphVertex argument should contain updated data - * - * @param graphVertex - * @return - */ - public Either updateVertex(GraphVertex graphVertex) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId()); - try { - graphVertex.updateMetadataJsonWithCurrentMetadataProperties(); - setVertexProperties(graphVertex.getVertex(), graphVertex); - - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - return Either.left(graphVertex); - } - - /** - * Fetches vertices by uniqueId according to received parse flag - * - * @param verticesToGet - * @return - */ - public Either, TitanOperationStatus> getVerticesByUniqueIdAndParseFlag(Map> verticesToGet) { - - Either, TitanOperationStatus> result = null; - Map vertices = new HashMap<>(); - TitanOperationStatus titatStatus; - Either getVertexRes = null; - for (Map.Entry> entry : verticesToGet.entrySet()) { - if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) { - getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue()); - } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) { - getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue()); - } - if (getVertexRes == null) { - titatStatus = TitanOperationStatus.ILLEGAL_ARGUMENT; - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus); - return Either.right(titatStatus); - } - if (getVertexRes.isRight()) { - titatStatus = getVertexRes.right().value(); - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus); - result = Either.right(titatStatus); - break; - } else { - vertices.put(entry.getKey(), getVertexRes.left().value()); - } - } - if (result == null) { - result = Either.left(vertices); - } - return result; - } - - /** - * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge - * - * @param from - * @param to - * @param label - * @param edgeToCopy - * @return - */ - public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) { - return createEdge(from, to, label, getEdgeProperties(edgeToCopy)); - } - - public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex!=null ? fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL", - toVertex!=null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL"); - - TitanOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge); - if (result == TitanOperationStatus.OK) { - prevEdge.remove(); - } - return result; - } - - /** - * Replaces previous label of edge with new label - * - * @param fromVertex - * @param toVertex - * @param prevLabel - * @param newLabel - * @return - */ - public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) { - - TitanOperationStatus result = null; - Iterator prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name()); - if (prevEdgeIter == null || !prevEdgeIter.hasNext()) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), - toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty())); - result = TitanOperationStatus.NOT_FOUND; - } - if (result == null) { - result = replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel); - } - return result; - } - - /** - * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too. - * - * - * @param vertex - * @param properties - * @return - */ - public TitanOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map properties) { - try { - if (!MapUtils.isEmpty(properties)) { - String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value(); - Map jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr); - for (Map.Entry property : properties.entrySet()) { - vertex.property(property.getKey().getProperty(), property.getValue()); - jsonMetadataMap.put(property.getKey().getProperty(), property.getValue()); - } - vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap)); - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage()); - return TitanGraphClient.handleTitanException(e); - } - return TitanOperationStatus.OK; - } - - public TitanOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) { - try { - Iterator edges = vertex.getVertex().edges(direction, label.name()); - - while (edges.hasNext()) { - Edge edge = edges.next(); - Vertex secondVertex; - Direction reverseDirection; - if (direction == Direction.IN) { - secondVertex = edge.outVertex(); - reverseDirection = Direction.OUT; - } else { - secondVertex = edge.inVertex(); - reverseDirection = Direction.IN; - } - edge.remove(); - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex()); - - Iterator restOfEdges = secondVertex.edges(reverseDirection, label.name()); - if (!restOfEdges.hasNext()) { - secondVertex.remove(); - CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId()); - } - } - } catch (Exception e) { - CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e); - return TitanGraphClient.handleTitanException(e); - } - return TitanOperationStatus.OK; - } - - public Object getProperty(TitanVertex vertex, String key) { - PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key); - return vertex.valueOrNull(propertyKey); - } - - public Object getProperty(Edge edge, EdgePropertyEnum key) { - Object value = null; - try { - Property property = edge.property(key.getProperty()); - if (property != null) { - value = property.orElse(null); - if (value != null && key == EdgePropertyEnum.INSTANCES) { - return JsonParserUtils.toList((String) value, String.class); - } - return value; - } - } catch (Exception e) { - - } - return value; - } - - /** - * - * @param vertexA - * @param vertexB - * @param label - * @param direction - * @return - */ - public TitanOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) { - TitanOperationStatus result = deleteEdgeByDirection(vertexA, direction, label); - if (result != TitanOperationStatus.OK) { - logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result); - return result; - } - TitanOperationStatus createRelation; - if (direction == Direction.IN) { - createRelation = createEdge(vertexB, vertexA, label, null); - } else { - createRelation = createEdge(vertexA, vertexB, label, null); - } - if (createRelation != TitanOperationStatus.OK) { - return createRelation; - } - return TitanOperationStatus.OK; - } - - public Either getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map properties) { - Either getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse); - if (getVertexRes.isRight()) { - return Either.right(getVertexRes.right().value()); - } - return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties); - } -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractJanusGraphVertexHeal.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractJanusGraphVertexHeal.java new file mode 100644 index 0000000000..f60a063a0a --- /dev/null +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractJanusGraphVertexHeal.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 AbstractJanusGraphVertexHeal implements Heal { + +} 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 deleted file mode 100644 index e01ddab989..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/heal/AbstractTitanVertexHeal.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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/titan/HealingTitanGenericDao.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java deleted file mode 100644 index 37546a5c2a..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/HealingTitanGenericDao.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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/QueryType.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/QueryType.java deleted file mode 100644 index 689ed32a8a..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/QueryType.java +++ /dev/null @@ -1,28 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao.titan; - -/** - * Created by mlando on 9/21/2016. - */ -public enum QueryType { - HAS, HAS_NOT -} 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 deleted file mode 100644 index 2123910650..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java +++ /dev/null @@ -1,1769 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao.titan; - -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.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.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.beans.factory.annotation.Qualifier; - -public class TitanGenericDao { - - private static final String FAILED_TO_RETRIEVE_GRAPH_STATUS_IS = "Failed to retrieve graph. status is {}"; - private static final String NO_EDGES_IN_GRAPH_FOR_CRITERIA = "No edges in graph for criteria"; - private static final String FAILED_TO_CREATE_EDGE_FROM_TO = "Failed to create edge from [{}] to [{}]"; - private TitanGraphClient titanClient; - private static Logger log = Logger.getLogger(TitanGenericDao.class.getName()); - private static final String LOCK_NODE_PREFIX = "lock_"; - - public TitanGenericDao(@Qualifier("titan-client") TitanGraphClient titanClient) { - this.titanClient = titanClient; - log.info("** TitanGenericDao created"); - } - - public TitanOperationStatus commit() { - log.debug("doing commit."); - return titanClient.commit(); - } - - public TitanOperationStatus rollback() { - log.error("Going to execute rollback on graph."); - return titanClient.rollback(); - } - - public void handleTransactionCommitRollback(boolean inTransaction, Either result) { - if (!inTransaction) { - if (result == null || result.isRight()) { - rollback(); - } else { - commit(); - } - } - } - - public Either getGraph() { - return titanClient.getGraph(); - } - - // For healthCheck - public boolean isGraphOpen() { - return titanClient.getHealth(); - } - - /** - * - * @param node - * @param clazz - * @return - */ - public Either createNode(T node, Class clazz) { - log.debug("try to create node for ID [{}]", node.getKeyValueId()); - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - T newNode; - try { - TitanGraph tGraph = graph.left().value(); - - Vertex vertex = tGraph.addVertex(); - - vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel()); - - Map properties = node.toGraphMap(); - if (properties != null) { - setProperties(vertex, properties); - } - Map newProps = getProperties(vertex); - newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz); - log.debug("created node for props : {}", newProps); - log.debug("Node was created for ID [{}]", node.getKeyValueId()); - return Either.left(newNode); - - } catch (Exception e) { - log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value()); - return Either.right(graph.right().value()); - } - } - - public Either createNode(GraphNode node) { - log.debug("try to create node for ID [{}]", node.getKeyValueId()); - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanVertex vertex = tGraph.addVertex(); - - vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel()); - - Map properties = node.toGraphMap(); - if (properties != null) { - setProperties(vertex, properties); - } - log.debug("Node was created for ID [{}]", node.getKeyValueId()); - return Either.left(vertex); - - } catch (Exception e) { - log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value()); - return Either.right(graph.right().value()); - } - } - - /** - * - * @param relation - * @return - */ - public Either createRelation(GraphRelation relation) { - log.debug("try to create relation from [{}] to [{}] ", relation.getFrom(), relation.getTo()); - - RelationEndPoint from = relation.getFrom(); - RelationEndPoint to = relation.getTo(); - ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); - ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); - - return createEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap()); - - } - - private Either createEdge(String type, ImmutablePair from, ImmutablePair to, String fromLabel, String toLabel, Map properties) { - Either graph = titanClient.getGraph(); - - if (graph.isLeft()) { - try { - Either fromV = getVertexByPropertyAndLabel(from.getKey(), from.getValue(), fromLabel); - if (fromV.isRight()) { - TitanOperationStatus error = fromV.right().value(); - if (TitanOperationStatus.NOT_FOUND.equals(error)) { - return Either.right(TitanOperationStatus.INVALID_ID); - } else { - return Either.right(error); - } - } - Either toV = getVertexByPropertyAndLabel(to.getKey(), to.getValue(), toLabel); - if (toV.isRight()) { - TitanOperationStatus error = toV.right().value(); - if (TitanOperationStatus.NOT_FOUND.equals(error)) { - return Either.right(TitanOperationStatus.INVALID_ID); - } else { - return Either.right(error); - } - } - - Vertex fromVertex = fromV.left().value(); - Vertex toVertex = toV.left().value(); - Edge edge = fromVertex.addEdge(type, toVertex); - - if (properties != null) { - - setProperties(edge, properties); - } - - Vertex vertexOut = edge.outVertex(); - Vertex vertexIn = edge.inVertex(); - - GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); - GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); - - GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); - - return Either.left(newRelation); - } catch (Exception e) { - log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, from, to, e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - log.debug("Failed to create edge from [{}] to [{}] {}", from, to, graph.right().value()); - return Either.right(graph.right().value()); - } - } - - public TitanOperationStatus createEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { - try { - Edge edge = addEdge(vertexOut, vertexIn, type, properties); - } catch (Exception e) { - log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e); - return TitanGraphClient.handleTitanException(e); - } - return TitanOperationStatus.OK; - - } - - private Edge addEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { - Edge edge = vertexOut.addEdge(type.getProperty(), vertexIn); - - if (properties != null) { - - setProperties(edge, properties); - } - return edge; - } - - /** - * creates an identical edge in the graph - * @param edge - * @return the copy operation status - */ - public Either copyEdge(Vertex out, Vertex in, Edge edge) { - GraphEdgeLabels byName = GraphEdgeLabels.getByName(edge.label()); - return this.saveEdge(out, in, byName, edgePropertiesToMap(edge)); - } - - private Map edgePropertiesToMap(Edge edge) { - Iterable> propertiesIterable = edge::properties; - return StreamSupport.stream(propertiesIterable.spliterator(), false).collect(Collectors.toMap(Property::key, Property::value)); - } - - public Either saveEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map properties) { - try { - Edge edge = addEdge(vertexOut, vertexIn, type, properties); - return Either.left(edge); - } catch (Exception e) { - log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } - - public TitanOperationStatus createEdge(TitanVertex vertexOut, GraphNode to, GraphEdgeLabels type, Map properties) { - - TitanVertex vertexIn; - Either toV = getVertexByPropertyAndLabel(to.getUniqueIdKey(), to.getUniqueId(), to.getLabel()); - if (toV.isRight()) { - TitanOperationStatus error = toV.right().value(); - if (TitanOperationStatus.NOT_FOUND.equals(error)) { - return TitanOperationStatus.INVALID_ID; - } else { - return error; - } - } - vertexIn = (TitanVertex) toV.left().value(); - return createEdge(vertexOut, vertexIn, type, properties); - } - - /** - * - * @param from - * @param to - * @param label - * @param properties - * @return - */ - public Either createRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map properties) { - log.debug("try to create relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); - return createEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties); - } - - public Either replaceRelationLabel(GraphNode from, GraphNode to, GraphEdgeLabels label, GraphEdgeLabels newLabel) { - - log.debug("try to replace relation {} to {} from [{}] to [{}]", label.name(), newLabel.name(), from.getKeyValueId(), to.getKeyValueId()); - Either getRelationResult = getRelation(from, to, label); - if (getRelationResult.isRight()) { - return getRelationResult; - } - - GraphRelation origRelation = getRelationResult.left().value(); - Either createRelationResult = createRelation(from, to, newLabel, origRelation.toGraphMap()); - if (createRelationResult.isRight()) { - return createRelationResult; - } - - Either deleteRelationResult = deleteRelation(origRelation); - if (deleteRelationResult.isRight()) { - return deleteRelationResult; - } - return Either.left(createRelationResult.left().value()); - } - - /** - * - * @param keyName - * @param keyValue - * @param clazz - * @return - */ - public Either getNode(String keyName, Object keyValue, Class clazz) { - - log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue); - - Either vertexByProperty = getVertexByProperty(keyName, keyValue); - - if (vertexByProperty.isLeft()) { - try { - Vertex vertex = vertexByProperty.left().value(); - Map properties = getProperties(vertex); - T node = GraphElementFactory.createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties, clazz); - return Either.left(node); - } catch (Exception e) { - log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value()); - return Either.right(vertexByProperty.right().value()); - } - } - - /** - * - * @param from - * @param to - * @param label - * @return - */ - public Either getRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) { - log.debug("try to get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); - - Either edge = getEdgeByNodes(from, to, label); - - if (edge.isLeft()) { - try { - Map properties = getProperties(edge.left().value()); - GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, from, to); - return Either.left(relation); - } catch (Exception e) { - log.debug("Failed to get get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId(), e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - log.debug("Failed to get get relation from [{}] to [{}] {}", from.getKeyValueId(), to.getKeyValueId(), edge.right().value()); - return Either.right(edge.right().value()); - } - } - - public Either getEdgeByNodes(GraphNode from, GraphNode to, GraphEdgeLabels label) { - ImmutablePair keyValueIdFrom = from.getKeyValueId(); - ImmutablePair keyValueIdTo = to.getKeyValueId(); - - return getEdgeByVerticies(keyValueIdFrom.getKey(), keyValueIdFrom.getValue(), keyValueIdTo.getKey(), keyValueIdTo.getValue(), label.getProperty()); - } - - public Either deleteIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { - - Either edgeByCriteria = getIncomingEdgeByCriteria(to, label, props); - if (edgeByCriteria.isLeft()) { - Either graph = getGraph(); - if (graph.isLeft()) { - Edge edge = edgeByCriteria.left().value(); - log.debug("delete edge {} to {} ", label.getProperty(), to.getUniqueId()); - edge.remove(); - Map properties = getProperties(edge); - Vertex fromVertex = edge.outVertex(); - String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); - GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class); - GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to); - return Either.left(relation); - } else { - log.debug("failed to get graph"); - return Either.right(graph.right().value()); - } - - } else { - log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId()); - return Either.right(edgeByCriteria.right().value()); - } - - } - - public Either getIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { - - Either edgeByCriteria = getIncomingEdgeByCriteria(to, label, props); - if (edgeByCriteria.isLeft()) { - Either graph = getGraph(); - if (graph.isLeft()) { - Edge edge = edgeByCriteria.left().value(); - Map properties = getProperties(edge); - Vertex fromVertex = edge.outVertex(); - String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); - GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class); - GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to); - return Either.left(relation); - } else { - log.debug("failed to get graph"); - return Either.right(graph.right().value()); - } - - } else { - log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId()); - return Either.right(edgeByCriteria.right().value()); - } - - } - - public Either getIncomingEdgeByCriteria(GraphNode to, GraphEdgeLabels label, Map props) { - - ImmutablePair keyValueIdTo = to.getKeyValueId(); - - Either vertexFrom = getVertexByProperty(keyValueIdTo.getKey(), keyValueIdTo.getValue()); - if (vertexFrom.isRight()) { - return Either.right(vertexFrom.right().value()); - } - Vertex vertex = vertexFrom.left().value(); - TitanVertex titanVertex = (TitanVertex) vertex; - TitanVertexQuery query = titanVertex.query(); - query = query.labels(label.getProperty()); - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey(), entry.getValue()); - } - } - Edge matchingEdge = null; - Iterable edges = query.edges(); - if (edges == null) { - log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - Iterator eIter = edges.iterator(); - if (eIter.hasNext()) { - matchingEdge = eIter.next(); - } - - if (matchingEdge == null) { - log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - return Either.left(matchingEdge); - } - - public Either getEdgeByVerticies(String keyNameFrom, Object keyValueFrom, String keyNameTo, Object keyValueTo, String label) { - Either graph = titanClient.getGraph(); - - if (graph.isLeft()) { - try { - Either vertexFrom = getVertexByProperty(keyNameFrom, keyValueFrom); - if (vertexFrom.isRight()) { - return Either.right(vertexFrom.right().value()); - } - Iterable edges = vertexFrom.left().value().query().labels(label).edges(); - Iterator eIter = edges.iterator(); - while (eIter.hasNext()) { - Edge edge = eIter.next(); - Vertex vertexIn = edge.inVertex(); - if (vertexIn.value(keyNameTo) != null && vertexIn.value(keyNameTo).equals(keyValueTo) && label.equals(edge.label())) { - return Either.left(edge); - } - } - log.debug("No relation in graph from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo); - return Either.right(TitanOperationStatus.NOT_FOUND); - } catch (Exception e) { - log.debug("Failed to get get relation from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo, e); - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getEdgesForNode(GraphNode node, Direction requestedDirection) { - - Either, TitanOperationStatus> result; - - ImmutablePair keyValueId = node.getKeyValueId(); - Either eitherVertex = getVertexByProperty(keyValueId.getKey(), keyValueId.getValue()); - - if (eitherVertex.isLeft()) { - List edges = prepareEdgesList(eitherVertex.left().value(), requestedDirection); - - result = Either.left(edges); - } else { - result = Either.right(eitherVertex.right().value()); - } - return result; - } - - private List prepareEdgesList(Vertex vertex, Direction requestedDirection) { - List edges = new ArrayList<>(); - Iterator edgesItr = ((TitanVertex) vertex).query().edges().iterator(); - while (edgesItr.hasNext()) { - Edge edge = edgesItr.next(); - Direction currEdgeDirection = getEdgeDirection(vertex, edge); - if (currEdgeDirection == requestedDirection || requestedDirection == Direction.BOTH) { - edges.add(edge); - } - - } - return edges; - } - - private Direction getEdgeDirection(Vertex vertex, Edge edge) { - Direction result; - Vertex vertexOut = edge.outVertex(); - if (vertexOut.equals(vertex)) { - result = Direction.OUT; - } else { - result = Direction.IN; - - } - return result; - } - - /** - * - * @param from - * @param to - * @param label - * @param properties - * @return - */ - public Either updateRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map properties) { - log.debug("try to update relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); - return updateEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties); - } - - private Either updateEdge(String type, ImmutablePair from, ImmutablePair to, String fromLabel, String toLabel, Map properties) { - - Either edgeS = getEdgeByVerticies(from.getKey(), from.getValue(), to.getKey(), to.getValue(), type); - if (edgeS.isLeft()) { - - try { - Edge edge = edgeS.left().value(); - if (properties != null) { - setProperties(edge, properties); - } - - Vertex vertexOut = edge.outVertex(); - Vertex vertexIn = edge.inVertex(); - - GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); - GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); - - GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); - if (log.isDebugEnabled()) { - log.debug("Relation was updated from [{}] to [{}] ", from, to); - } - return Either.left(newRelation); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to update relation from [{}] to [{}] ", from, to, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to update relation from [{}] to [{}] {}", from, to, edgeS.right().value()); - } - return Either.right(edgeS.right().value()); - } - } - - /** - * - * @param relation - * @return - */ - public Either updateRelation(GraphRelation relation) { - log.debug("try to update relation from [{}] to [{}]", relation.getFrom(), relation.getTo()); - RelationEndPoint from = relation.getFrom(); - RelationEndPoint to = relation.getTo(); - ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); - ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); - - return updateEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap()); - - } - - private Either getVertexByPropertyAndLabel(String name, Object value, String label) { - - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - @SuppressWarnings("unchecked") - Iterable vertecies = tGraph.query().has(name, value).has(GraphPropertiesDictionary.LABEL.getProperty(), label).vertices(); - - java.util.Iterator iterator = vertecies.iterator(); - if (iterator.hasNext()) { - Vertex vertex = iterator.next(); - return Either.left(vertex); - } - if (log.isDebugEnabled()) { - log.debug("No vertex in graph for key =" + name + " and value = " + value + " label = " + label); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to get vertex in graph for key ={} and value = {} label = {}",name,value,label); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (log.isDebugEnabled()) { - log.debug("No vertex in graph for key ={} and value = {} label = {} error : {}",name,value,label,graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either getVertexByProperty(String name, Object value) { - - Either graph = titanClient.getGraph(); - if (value == null) { - if (log.isDebugEnabled()) { - log.debug("No vertex in graph for key = {} and value = {}", name, value); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - @SuppressWarnings("unchecked") - Iterable vertecies = tGraph.query().has(name, value).vertices(); - - java.util.Iterator iterator = vertecies.iterator(); - if (iterator.hasNext()) { - TitanVertex vertex = iterator.next(); - return Either.left(vertex); - } else { - if (log.isDebugEnabled()) { - log.debug("No vertex in graph for key ={} and value = {}", name, value); - } - return Either.right(TitanOperationStatus.NOT_FOUND); - } - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to get vertex in graph for key = {} and value = ", name, value); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - if (log.isDebugEnabled()) { - log.debug("No vertex in graph for key = {} and value = {} error : {}", name, value, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map hasProps, Map hasNotProps, Class clazz) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); - - if (hasProps != null && !hasProps.isEmpty()) { - for (Map.Entry entry : hasProps.entrySet()) { - query = query.has(entry.getKey(), entry.getValue()); - } - } - if (hasNotProps != null && !hasNotProps.isEmpty()) { - for (Map.Entry entry : hasNotProps.entrySet()) { - query = query.hasNot(entry.getKey(), entry.getValue()); - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - Vertex vertex = iterator.next(); - - Map newProp = getProperties(vertex); - - T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); - result.add(element); - } - if (log.isDebugEnabled()) { - log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties has = {}, properties hasNot = {} is {}", type, hasProps, hasNotProps, result.size()); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(result); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type = {}", type, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Class clazz, List> props) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); - for (ImmutableTriple prop : props) { - if (QueryType.HAS.equals(prop.getLeft())) { - query = query.has(prop.getMiddle(), prop.getRight()); - } else { - query = query.hasNot(prop.getMiddle(), prop.getRight()); - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - Vertex vertex = iterator.next(); - - Map newProp = getProperties(vertex); - - T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); - result.add(element); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(result); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type = {}", type, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map props, Class clazz) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey(), entry.getValue()); - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - Vertex vertex = iterator.next(); - - Map newProp = getProperties(vertex); - - T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); - result.add(element); - } - if (log.isDebugEnabled()) { - log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size()); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(result); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getByCriteriaWithPredicate(NodeTypeEnum type, Map> props, Class clazz) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - try { - TitanGraph tGraph = graph.left().value(); - - TitanGraphQuery query = tGraph.query(); - query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); - - if (props != null && !props.isEmpty()) { - TitanPredicate predicate = null; - Object object = null; - for (Map.Entry> entry : props.entrySet()) { - predicate = entry.getValue().getKey(); - object = entry.getValue().getValue(); - query = query.has(entry.getKey(), predicate, object); - } - } - Iterable vertices = query.vertices(); - if (vertices == null) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - Iterator iterator = vertices.iterator(); - List result = new ArrayList<>(); - - while (iterator.hasNext()) { - Vertex vertex = iterator.next(); - - Map newProp = getProperties(vertex); - T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); - result.add(element); - } - if (result.size() == 0) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - if (log.isDebugEnabled()) { - log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props); - } - return Either.left(result); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - if (log.isDebugEnabled()) { - log.debug("Failed get by criteria for type = {} and properties = {} error : {}", type, props, graph.right().value()); - } - return Either.right(graph.right().value()); - } - } - - public Either, TitanOperationStatus> getAll(NodeTypeEnum type, Class clazz) { - return getByCriteria(type, null, clazz); - } - - /** - * - * @param node - * @param clazz - * @return - */ - public Either updateNode(GraphNode node, Class clazz) { - log.debug("Try to update node for {}", node.getKeyValueId()); - - ImmutablePair keyValueId = node.getKeyValueId(); - Either vertexByProperty = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel()); - - if (vertexByProperty.isLeft()) { - try { - Vertex vertex = vertexByProperty.left().value(); - - Map mapProps = node.toGraphMap(); - - for (Map.Entry entry : mapProps.entrySet()) { - if (!entry.getKey().equals(node.getUniqueIdKey())) { - vertex.property(entry.getKey(), entry.getValue()); - } - } - - Either vertexByPropertyAndLabel = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel()); - if (vertexByPropertyAndLabel.isRight()) { - return Either.right(vertexByPropertyAndLabel.right().value()); - } else { - Map newProp = getProperties(vertexByPropertyAndLabel.left().value()); - T updateNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProp, clazz); - return Either.left(updateNode); - } - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to update node for {}", node.getKeyValueId(), e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to update node for {} error :{}", node.getKeyValueId(), vertexByProperty.right().value()); - } - return Either.right(vertexByProperty.right().value()); - } - - } - - public TitanOperationStatus updateVertex(GraphNode node, Vertex vertex) { - log.debug("Try to update node for {}", node.getKeyValueId()); - try { - - Map mapProps = node.toGraphMap(); - - for (Map.Entry entry : mapProps.entrySet()) { - if (!entry.getKey().equals(node.getUniqueIdKey())) { - vertex.property(entry.getKey(), entry.getValue()); - } - } - - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to update node for {}", node.getKeyValueId(), e); - } - return TitanGraphClient.handleTitanException(e); - } - return TitanOperationStatus.OK; - - } - - /** - * - * @param node - * @param clazz - * @return - */ - public Either deleteNode(GraphNode node, Class clazz) { - log.debug("Try to delete node for {}", node.getKeyValueId()); - ImmutablePair keyValueId = node.getKeyValueId(); - return deleteNode(keyValueId.getKey(), keyValueId.getValue(), clazz); - } - - /** - * - * @param keyName - * @param keyValue - * @param clazz - * @return - */ - public Either deleteNode(String keyName, Object keyValue, Class clazz) { - Either vertexByProperty = getVertexByProperty(keyName, keyValue); - - if (vertexByProperty.isLeft()) { - try { - Vertex vertex = vertexByProperty.left().value(); - - Map properties = getProperties(vertex); - if (properties != null) { - String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()); - - T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz); - if (node != null) { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - TitanGraph tGraph = graph.left().value(); - vertex.remove(); - } else { - return Either.right(graph.right().value()); - } - return Either.left(node); - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue); - } - return Either.right(TitanOperationStatus.MISSING_NODE_LABEL); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue); - } - return Either.right(TitanOperationStatus.MISSING_NODE_LABEL); - } - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to delete node for {} = {}", keyName, keyValue, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - - } else { - return Either.right(vertexByProperty.right().value()); - } - } - - public Either deleteRelation(GraphRelation relation) { - log.debug("try to delete relation from [{}] to [{}]", relation.getFrom(), relation.getTo()); - RelationEndPoint from = relation.getFrom(); - RelationEndPoint to = relation.getTo(); - ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); - ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); - - return deleteEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName()); - - } - - public Either isRelationExist(GraphNode from, GraphNode to, GraphEdgeLabels edgeLabel) { - return getEdgeByNodes(from, to, edgeLabel) - .left() - .map(edge -> true) - .right() - .bind(err -> err == TitanOperationStatus.NOT_FOUND ? Either.left(false): Either.right(err)); - } - - public Either deleteRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) { - log.debug("try to delete relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId()); - return deleteEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel()); - } - - private Either deleteEdge(String type, ImmutablePair fromKeyId, ImmutablePair toKeyId, String fromLabel, String toLabel) { - Either edgeS = getEdgeByVerticies(fromKeyId.getKey(), fromKeyId.getValue(), toKeyId.getKey(), toKeyId.getValue(), type); - if (edgeS.isLeft()) { - try { - Edge edge = edgeS.left().value(); - - Vertex vertexOut = edge.outVertex(); - Vertex vertexIn = edge.inVertex(); - - GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); - GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); - - GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); - - Either graph = titanClient.getGraph(); - - if (graph.isLeft()) { - edge.remove(); - ; - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to delete relation {} from {} to {} error : {}",type,fromKeyId,toKeyId,graph.right().value()); - } - return Either.right(graph.right().value()); - } - return Either.left(newRelation); - } catch (Exception e) { - if (log.isDebugEnabled()) { - log.debug("Failed to delete relation {} from {} to {}", type, fromKeyId, toKeyId, e); - } - return Either.right(TitanGraphClient.handleTitanException(e)); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, edgeS.right().value()); - } - return Either.right(edgeS.right().value()); - } - } - - public void setTitanGraphClient(TitanGraphClient titanGraphClient) { - this.titanClient = titanGraphClient; - } - - public Either deleteIncomingRelation(GraphRelation relation) { - - RelationEndPoint to = relation.getTo(); - ImmutablePair toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue()); - - return deleteIncomingEdge(relation.getType(), toKeyId); - - } - - private Either deleteIncomingEdge(String type, ImmutablePair toKeyId) { - - Either graph = titanClient.getGraph(); - - if (graph.isLeft()) { - Either rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue()); - if (rootVertexResult.isLeft()) { - Vertex rootVertex = rootVertexResult.left().value(); - Iterator edgesIterator = rootVertex.edges(Direction.IN, type); - if (edgesIterator != null) { - - Edge edge = null; - - if (edgesIterator.hasNext()) { - edge = edgesIterator.next(); - if (edgesIterator.hasNext()) { - return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL); - } - } else { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - log.debug("Find the tail vertex of the edge of type {} to vertex {}", type, toKeyId); - Vertex vertexOut = edge.outVertex(); - String fromLabel = vertexOut.value(GraphPropertiesDictionary.LABEL.getProperty()); - String toLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); - log.debug("The label of the outgoing vertex is {}", fromLabel); - GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class); - - GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class); - - GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn); - - edge.remove(); - - return Either.left(newRelation); - - } else { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - } else { - return Either.right(graph.right().value()); - } - - } else { - return Either.right(graph.right().value()); - } - - } - - public Either deleteOutgoingRelation(GraphRelation relation) { - - RelationEndPoint from = relation.getFrom(); - ImmutablePair fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue()); - - return deleteOutgoingEdge(relation.getType(), fromKeyId); - - } - - private Either deleteOutgoingEdge(String type, ImmutablePair toKeyId) { - - Either graph = titanClient.getGraph(); - - if (graph.isLeft()) { - Either rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue()); - if (rootVertexResult.isLeft()) { - Vertex rootVertex = rootVertexResult.left().value(); - Iterator edgesIterator = rootVertex.edges(Direction.OUT, type); - if (edgesIterator != null) { - - Edge edge = null; - - if (edgesIterator.hasNext()) { - edge = edgesIterator.next(); - if (edgesIterator.hasNext()) { - return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL); - } - } else { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - log.debug("Find the tail vertex of the edge of type {} to vertex ", type, toKeyId); - Vertex vertexIn = edge.inVertex(); - String toLabel = vertexIn.value(GraphPropertiesDictionary.LABEL.getProperty()); - String fromLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty()); - log.debug("The label of the tail vertex is {}", toLabel); - GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class); - - GraphNode nodeTo = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class); - - GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeFrom, nodeTo); - - edge.remove(); - - return Either.left(newRelation); - - } else { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - } else { - return Either.right(graph.right().value()); - } - - } else { - return Either.right(graph.right().value()); - } - } - - /** - * - * @param id - * @return - */ - - public TitanOperationStatus lockElement(String id, NodeTypeEnum type) { - - StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); - lockId.append(type.getName()).append("_").append(id); - return lockNode(lockId.toString()); - } - - public TitanOperationStatus lockElement(GraphNode node) { - - StringBuffer lockId = createLockElementId(node); - - return lockNode(lockId.toString()); - } - - private TitanOperationStatus lockNode(String lockId) { - TitanOperationStatus status = TitanOperationStatus.OK; - - GraphNodeLock lockNode = new GraphNodeLock(lockId); - - Either lockNodeNew = createNode(lockNode, GraphNodeLock.class); - if (lockNodeNew.isLeft()) { - log.debug("before commit, Lock node created for {}", lockId); - return titanClient.commit(); - } else { - Either graph = titanClient.getGraph(); - if (graph.isLeft()) { - TitanGraph tGraph = graph.left().value(); - Either vertex = getVertexByProperty(lockNode.getUniqueIdKey(), lockNode.getUniqueId()); - if (vertex.isLeft()) { - status = relockNode(lockNode, lockNodeNew, tGraph, vertex); - } else { - status = vertex.right().value(); - } - } else { - status = graph.right().value(); - } - } - return status; - } - - private TitanOperationStatus relockNode(GraphNodeLock lockNode, Either lockNodeNew, TitanGraph tGraph, Either vertex) { - TitanOperationStatus status = TitanOperationStatus.OK; - Long time = vertex.left().value().value(GraphPropertiesDictionary.CREATION_DATE.getProperty()); - Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getTitanLockTimeout(); - if (time + lockTimeout * 1000 < System.currentTimeMillis()) { - log.debug("Found not released lock node with id {}", lockNode.getUniqueId()); - vertex.left().value().remove(); - lockNodeNew = createNode(lockNode, GraphNodeLock.class); - if (lockNodeNew.isLeft()) { - log.debug("Lock node created for {}", lockNode.getUniqueIdKey()); - return titanClient.commit(); - } else { - log.debug("Failed Lock node for {} . Commit transacton for deleted previous vertex .", lockNode.getUniqueIdKey()); - titanClient.commit(); - status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew); - } - } else { - log.debug("Failed Lock node for {} rollback transacton", lockNode.getUniqueIdKey()); - titanClient.rollback(); - status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew); - } - return status; - } - - public Either>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, boolean withEdges) { - - List> immutablePairs = new ArrayList<>(); - - Either graphRes = titanClient.getGraph(); - if (graphRes.isRight()) { - log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); - return Either.right(graphRes.right().value()); - } - - TitanGraph titanGraph = graphRes.left().value(); - @SuppressWarnings("unchecked") - Iterable vertices = titanGraph.query().has(key, uniqueId).vertices(); - if (vertices == null || !vertices.iterator().hasNext()) { - return Either.right(TitanOperationStatus.INVALID_ID); - } - - Vertex rootVertex = vertices.iterator().next(); - - Iterator edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); - if (edgesCreatorIterator != null) { - while (edgesCreatorIterator.hasNext()) { - Edge edge = edgesCreatorIterator.next(); - GraphEdge graphEdge = null; - - if (withEdges) { - Map edgeProps = getProperties(edge); - GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); - graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); - } - - Vertex outgoingVertex = edge.inVertex(); - Map properties = getProperties(outgoingVertex); - T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); - - ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); - immutablePairs.add(immutablePair); - } - } - - if (immutablePairs.isEmpty()) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(immutablePairs); - - } - - public Either>, TitanOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) { - - List> immutablePairs = new ArrayList<>(); - - Either graphRes = titanClient.getGraph(); - if (graphRes.isRight()) { - log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); - return Either.right(graphRes.right().value()); - } - - TitanGraph titanGraph = graphRes.left().value(); - @SuppressWarnings("unchecked") - Iterable vertices = titanGraph.query().has(key, uniqueId).vertices(); - if (vertices == null || !vertices.iterator().hasNext()) { - return Either.right(TitanOperationStatus.INVALID_ID); - } - - Vertex rootVertex = vertices.iterator().next(); - - Iterator edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); - if (edgesCreatorIterator != null) { - while (edgesCreatorIterator.hasNext()) { - Edge edge = edgesCreatorIterator.next(); - TitanVertex vertex = (TitanVertex) edge.inVertex(); - - ImmutablePair immutablePair = new ImmutablePair<>(vertex, edge); - immutablePairs.add(immutablePair); - } - } - if (immutablePairs.isEmpty()) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(immutablePairs); - - } - - public Either>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { - return this.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, true); - } - - private TitanOperationStatus checkLockError(String lockId, Either lockNodeNew) { - TitanOperationStatus status; - TitanOperationStatus error = lockNodeNew.right().value(); - log.debug("Failed to Lock node for {} error = {}", lockId, error); - if (error.equals(TitanOperationStatus.TITAN_SCHEMA_VIOLATION) || error.equals(TitanOperationStatus.ILLEGAL_ARGUMENT)) { - status = TitanOperationStatus.ALREADY_LOCKED; - } else { - status = error; - } - return status; - } - - /** - * - * @param node - * @return - */ - public TitanOperationStatus releaseElement(GraphNode node) { - StringBuffer lockId = createLockElementId(node); - - return unlockNode(lockId); - } - - private TitanOperationStatus unlockNode(StringBuffer lockId) { - GraphNodeLock lockNode = new GraphNodeLock(lockId.toString()); - - Either lockNodeNew = deleteNode(lockNode, GraphNodeLock.class); - if (lockNodeNew.isLeft()) { - log.debug("Lock node released for lock id = {}", lockId); - return titanClient.commit(); - } else { - titanClient.rollback(); - TitanOperationStatus error = lockNodeNew.right().value(); - log.debug("Failed to Release node for lock id {} error = {}", lockId, error); - return error; - } - } - - public TitanOperationStatus releaseElement(String id, NodeTypeEnum type) { - StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); - lockId.append(type.getName()).append("_").append(id); - return unlockNode(lockId); - } - - private StringBuffer createLockElementId(GraphNode node) { - StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX); - lockId.append(node.getLabel()).append("_").append(node.getUniqueId()); - return lockId; - } - - public Either, TitanOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { - - Either>, TitanOperationStatus> childrenNodes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); - - if (childrenNodes.isRight()) { - return Either.right(childrenNodes.right().value()); - } - - List> value = childrenNodes.left().value(); - - if (value.size() > 1) { - return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE); - } - - return Either.left(value.get(0)); - - } - - public ImmutablePair getChildVertex(TitanVertex vertex, GraphEdgeLabels edgeType) { - - ImmutablePair pair = null; - Iterator edges = vertex.edges(Direction.OUT, edgeType.getProperty()); - if (edges.hasNext()) { - // get only first edge - Edge edge = edges.next(); - pair = new ImmutablePair<>((TitanVertex) edge.inVertex(), edge); - } - return pair; - } - - public Either>, TitanOperationStatus> getParentNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { - - List> immutablePairs = new ArrayList<>(); - - T data = null; - GraphEdge graphEdge = null; - - Either graphRes = titanClient.getGraph(); - if (graphRes.isRight()) { - log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes); - return Either.right(graphRes.right().value()); - } - - TitanGraph titanGraph = graphRes.left().value(); - @SuppressWarnings("unchecked") - Iterable vertices = titanGraph.query().has(key, uniqueId).vertices(); - if (vertices == null || !vertices.iterator().hasNext()) { - return Either.right(TitanOperationStatus.INVALID_ID); - } - - Vertex rootVertex = vertices.iterator().next(); - - Iterator edgesCreatorIterator = rootVertex.edges(Direction.IN, edgeType.name()); - if (edgesCreatorIterator != null) { - while (edgesCreatorIterator.hasNext()) { - Edge edge = edgesCreatorIterator.next(); - Map edgeProps = getProperties(edge); - GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); - graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); - - Vertex outgoingVertex = edge.outVertex(); - Map properties = getProperties(outgoingVertex); - data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); - - ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); - immutablePairs.add(immutablePair); - } - } - - if (immutablePairs.isEmpty()) { - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - return Either.left(immutablePairs); - - } - - public Either, TitanOperationStatus> getParentNode(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { - - Either>, TitanOperationStatus> parentNodesRes = this.getParentNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); - - if (parentNodesRes.isRight()) { - log.debug("failed to get edge key:{} uniqueId:{} edgeType {} nodeTypeEnum: {}, reason:{}", key, uniqueId, edgeType, nodeTypeEnum, parentNodesRes.right().value()); - return Either.right(parentNodesRes.right().value()); - } - - List> value = parentNodesRes.left().value(); - - if (value.size() > 1) { - return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE); - } - - return Either.left(value.get(0)); - } - - public Either, TitanOperationStatus> getChildByEdgeCriteria(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, Map edgeProperties) { - - Either outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(key, uniqueId, edgeType, edgeProperties); - if (outgoingEdgeByCriteria.isRight()) { - TitanOperationStatus status = outgoingEdgeByCriteria.right().value(); - log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}" + uniqueId, edgeType, edgeProperties); - return Either.right(status); - } - - Edge edge = outgoingEdgeByCriteria.left().value(); - Map edgeProps = getProperties(edge); - GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); - GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); - - Vertex outgoingVertex = edge.inVertex(); - Map properties = getProperties(outgoingVertex); - T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); - - ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); - - return Either.left(immutablePair); - } - - public Either, TitanOperationStatus> getChildByEdgeCriteria(TitanVertex vertex, GraphEdgeLabels edgeType, Map edgeProperties) { - - Either outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(vertex, edgeType, edgeProperties); - if (outgoingEdgeByCriteria.isRight()) { - TitanOperationStatus status = outgoingEdgeByCriteria.right().value(); - log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertex, edgeType, edgeProperties); - return Either.right(status); - } - Edge edge = outgoingEdgeByCriteria.left().value(); - - TitanVertex outgoingVertex = (TitanVertex) edge.inVertex(); - - ImmutablePair immutablePair = new ImmutablePair<>(outgoingVertex, edge); - - return Either.left(immutablePair); - } - - public Either getOutgoingEdgeByCriteria(String key, String value, GraphEdgeLabels label, Map props) { - - Either vertexFrom = getVertexByProperty(key, value); - if (vertexFrom.isRight()) { - TitanOperationStatus status = vertexFrom.right().value(); - if (status == TitanOperationStatus.NOT_FOUND) { - return Either.right(TitanOperationStatus.INVALID_ID); - } - return Either.right(status); - } - - return getOutgoingEdgeByCriteria(vertexFrom.left().value(), label, props); - } - - public Either getOutgoingEdgeByCriteria(TitanVertex vertex, GraphEdgeLabels label, Map props) { - - TitanVertexQuery query = vertex.query(); - query = query.direction(Direction.OUT).labels(label.getProperty()); - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey(), entry.getValue()); - } - } - Edge matchingEdge = null; - Iterable edges = query.edges(); - if (edges == null) { - log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - Iterator eIter = edges.iterator(); - if (eIter.hasNext()) { - matchingEdge = eIter.next(); - } - - if (matchingEdge == null) { - log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - return Either.left(matchingEdge); - } - - public Either>, TitanOperationStatus> deleteChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz) { - - List> result = new ArrayList<>(); - - Either>, TitanOperationStatus> childrenNodesRes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz); - - if (childrenNodesRes.isRight()) { - TitanOperationStatus status = childrenNodesRes.right().value(); - return Either.right(status); - } - - List> list = childrenNodesRes.left().value(); - for (ImmutablePair pair : list) { - T node = pair.getKey(); - Either deleteNodeRes = this.deleteNode(node, clazz); - if (deleteNodeRes.isRight()) { - TitanOperationStatus status = deleteNodeRes.right().value(); - log.error("Failed to delete node {} . status is {}", node, status); - return Either.right(status); - } - ImmutablePair deletedPair = new ImmutablePair<>(node, pair.getValue()); - result.add(deletedPair); - } - - return Either.left(result); - - } - - public void setProperties(Element element, Map properties) { - - if (properties != null && !properties.isEmpty()) { - - Object[] propertyKeyValues = new Object[properties.size() * 2]; - int i = 0; - for (Entry entry : properties.entrySet()) { - propertyKeyValues[i++] = entry.getKey(); - propertyKeyValues[i++] = entry.getValue(); - } - - ElementHelper.attachProperties(element, propertyKeyValues); - - } - - } - - public Map getProperties(Element element) { - - Map result = new HashMap<>(); - - if (element != null && element.keys() != null && element.keys().size() > 0) { - Map propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()])); - - for (Entry entry : propertyMap.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue().value(); - - result.put(key, value); - } - } - return result; - } - - public Object getProperty(TitanVertex vertex, String key) { - PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key); - return vertex.valueOrNull(propertyKey); - } - - public Object getProperty(Edge edge, String key) { - Object value = null; - Property property = edge.property(key); - if (property != null) { - return property.orElse(null); - } - return value; - } - - public Either>, TitanOperationStatus> getChildrenByEdgeCriteria(Vertex vertex, String vertexUniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class clazz, - Map edgeProperties) { - - List> result = new ArrayList<>(); - - Either, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgesByCriteria(vertex, edgeType, edgeProperties); - if (outgoingEdgeByCriteria.isRight()) { - TitanOperationStatus status = outgoingEdgeByCriteria.right().value(); - log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertexUniqueId, edgeType, edgeProperties); - return Either.right(status); - } - - List edges = outgoingEdgeByCriteria.left().value(); - if (edges != null) { - for (Edge edge : edges) { - Map edgeProps = getProperties(edge); - GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); - GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); - - Vertex outgoingVertex = edge.inVertex(); - Map properties = getProperties(outgoingVertex); - T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz); - - ImmutablePair immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge); - result.add(immutablePair); - } - } - - return Either.left(result); - } - - public Either, TitanOperationStatus> getOutgoingEdgesByCriteria(Vertex vertexFrom, GraphEdgeLabels label, Map props) { - - List edgesResult = new ArrayList<>(); - - TitanVertex titanVertex = (TitanVertex) vertexFrom; - TitanVertexQuery query = titanVertex.query(); - - query = query.direction(Direction.OUT).labels(label.getProperty()); - - if (props != null && !props.isEmpty()) { - for (Map.Entry entry : props.entrySet()) { - query = query.has(entry.getKey(), entry.getValue()); - } - } - - Iterable edges = query.edges(); - Iterator eIter = edges.iterator(); - if (edges == null || !eIter.hasNext()) { - log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - - while (eIter.hasNext()) { - Edge edge = eIter.next(); - edgesResult.add(edge); - } - - if (edgesResult.isEmpty()) { - log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props); - return Either.right(TitanOperationStatus.NOT_FOUND); - } - return Either.left(edgesResult); - - } - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGraphClient.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGraphClient.java deleted file mode 100644 index 9d5ff9d226..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGraphClient.java +++ /dev/null @@ -1,408 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao.titan; - -import com.thinkaurelius.titan.core.*; -import com.thinkaurelius.titan.core.schema.ConsistencyModifier; -import com.thinkaurelius.titan.core.schema.TitanGraphIndex; -import com.thinkaurelius.titan.core.schema.TitanManagement; -import com.thinkaurelius.titan.core.util.TitanCleanup; -import com.thinkaurelius.titan.diskstorage.ResourceUnavailableException; -import com.thinkaurelius.titan.diskstorage.locking.PermanentLockingException; -import com.thinkaurelius.titan.graphdb.database.idassigner.IDPoolExhaustedException; -import fj.data.Either; -import org.apache.commons.configuration.BaseConfiguration; -import org.apache.tinkerpop.gremlin.structure.T; -import org.apache.tinkerpop.gremlin.structure.Vertex; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.dao.DAOTitanStrategy; -import org.openecomp.sdc.be.dao.TitanClientStrategy; -import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.concurrent.*; - - -@Component("titan-client") -public class TitanGraphClient { - private static Logger logger = LoggerFactory.getLogger(TitanGraphClient.class.getName()); - private static Logger healthLogger = LoggerFactory.getLogger("titan.healthcheck"); - - private static final String HEALTH_CHECK = GraphPropertiesDictionary.HEALTH_CHECK.getProperty(); - private static final String OK = "GOOD"; - - public TitanGraphClient() { - } - - private class HealthCheckTask implements Callable { - @Override - public Vertex call() { - - TitanVertex v = (TitanVertex) graph.query().has(HEALTH_CHECK, OK).vertices().iterator().next(); - TitanVertexProperty property = v.property("healthcheck", OK + "_" + System.currentTimeMillis()); - healthLogger.trace("Health Check Node Found...{}", v.property(HEALTH_CHECK)); - graph.tx().commit(); - - return v; - } - } - - private class HealthCheckScheduledTask implements Runnable { - @Override - public void run() { - healthLogger.trace("Executing TITAN Health Check Task - Start"); - boolean healthStatus = isGraphOpen(); - healthLogger.trace("Executing TITAN Health Check Task - Status = {}", healthStatus); - if (healthStatus != lastHealthState) { - logger.trace("TITAN Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus); - lastHealthState = healthStatus; - logAlarm(); - } - } - } - - private class ReconnectTask implements Runnable { - @Override - public void run() { - logger.trace("Trying to reconnect to Titan..."); - if (graph == null) { - createGraph(titanCfgFile); - } - } - } - - private TitanGraph graph; - - // Health Check Variables - - /** - * This executor will execute the health check task on a callable task that can be executed with a timeout. - */ - ExecutorService healthCheckExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "Titan-Health-Check-Thread"); - } - }); - private long healthCheckReadTimeout = 2; - HealthCheckTask healthCallableTask = new HealthCheckTask(); - HealthCheckScheduledTask healthCheckScheduledTask = new HealthCheckScheduledTask(); - boolean lastHealthState = false; - - // Reconnection variables - private ScheduledExecutorService reconnectScheduler = null; - private ScheduledExecutorService healthCheckScheduler = null; - private Runnable reconnectTask = null; - private long reconnectInterval = 3; - @SuppressWarnings("rawtypes") - private Future reconnectFuture; - - private String titanCfgFile = null; - TitanClientStrategy titanClientStrategy; - - public TitanGraphClient(TitanClientStrategy titanClientStrategy) { - super(); - this.titanClientStrategy = titanClientStrategy; - - // Initialize a single threaded scheduler for health-check - this.healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "Titan-Health-Check-Task"); - } - }); - - healthCheckReadTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getTitanHealthCheckReadTimeout(2); - reconnectInterval = ConfigurationManager.getConfigurationManager().getConfiguration().getTitanReconnectIntervalInSeconds(3); - - logger.info("** TitanGraphClient created"); - } - - @PostConstruct - public TitanOperationStatus createGraph() { - - logger.info("** createGraph started **"); - - if (ConfigurationManager.getConfigurationManager().getConfiguration().getTitanInMemoryGraph()) { - BaseConfiguration conf = new BaseConfiguration(); - conf.setProperty("storage.backend", "inmemory"); - graph = TitanFactory.open(conf); - createTitanSchema(); - logger.info("** in memory graph created"); - return TitanOperationStatus.OK; - } else { - this.titanCfgFile = titanClientStrategy.getConfigFile(); - if (titanCfgFile == null || titanCfgFile.isEmpty()) { - titanCfgFile = "config/titan.properties"; - } - - // yavivi - // In case connection failed on init time, schedule a reconnect task - // in the BG - TitanOperationStatus status = createGraph(titanCfgFile); - logger.debug("Create Titan graph status {}", status); - if (status != TitanOperationStatus.OK) { - this.startReconnectTask(); - } - - return status; - } - } - - private void startHealthCheckTask() { - this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS); - } - - /** - * This method will be invoked ONLY on init time in case Titan storage is down. - */ - private void startReconnectTask() { - this.reconnectTask = new ReconnectTask(); - // Initialize a single threaded scheduler - this.reconnectScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "Titan-Reconnect-Task"); - } - }); - - logger.info("Scheduling reconnect task {} with interval of {} seconds", reconnectTask, reconnectInterval); - reconnectFuture = this.reconnectScheduler.scheduleAtFixedRate(this.reconnectTask, 0, this.reconnectInterval, TimeUnit.SECONDS); - } - - public void cleanupGraph() { - if (graph != null) { - // graph.shutdown(); - graph.close(); - TitanCleanup.clear(graph); - } - } - - private boolean graphInitialized(){ - TitanManagement graphMgmt = graph.openManagement(); - return graphMgmt.containsPropertyKey(HEALTH_CHECK) && graphMgmt.containsGraphIndex(HEALTH_CHECK); - } - - - public TitanOperationStatus createGraph(String titanCfgFile) { - logger.info("** open graph with {} started", titanCfgFile); - try { - logger.info("openGraph : try to load file {}", titanCfgFile); - graph = TitanFactory.open(titanCfgFile); - if (graph.isClosed() || !graphInitialized()) { - logger.error("titan graph was not initialized"); - return TitanOperationStatus.NOT_CREATED; - } - - } catch (Exception e) { - this.graph = null; - logger.info("createGraph : failed to open Titan graph with configuration file: {}", titanCfgFile); - logger.debug("createGraph : failed with exception.", e); - return TitanOperationStatus.NOT_CONNECTED; - } - - logger.info("** Titan graph created "); - - // Do some post creation actions - this.onGraphOpened(); - - return TitanOperationStatus.OK; - } - - private void onGraphOpened() { - // if a reconnect task is running, cancel it. - if (this.reconnectFuture != null) { - logger.info("** Cancelling Titan reconnect task"); - reconnectFuture.cancel(true); - } - - // create health-check node - if (!graph.query().has(HEALTH_CHECK, OK).vertices().iterator().hasNext()) { - logger.trace("Healthcheck Singleton node does not exist, Creating healthcheck node..."); - Vertex healthCheckNode = graph.addVertex(); - healthCheckNode.property(HEALTH_CHECK, OK); - logger.trace("Healthcheck node created successfully. ID={}", healthCheckNode.property(T.id.getAccessor())); - graph.tx().commit(); - } else { - logger.trace("Skipping Healthcheck Singleton node creation. Already exist..."); - } - this.startHealthCheckTask(); - } - - - public Either getGraph() { - if (graph != null) { - return Either.left(graph); - } else { - return Either.right(TitanOperationStatus.NOT_CREATED); - } - } - - public TitanOperationStatus commit() { - if (graph != null) { - try { - graph.tx().commit(); - return TitanOperationStatus.OK; - } catch (Exception e) { - return handleTitanException(e); - } - } else { - return TitanOperationStatus.NOT_CREATED; - } - } - - public TitanOperationStatus rollback() { - if (graph != null) { - try { - // graph.rollback(); - graph.tx().rollback(); - return TitanOperationStatus.OK; - } catch (Exception e) { - return handleTitanException(e); - } - } else { - return TitanOperationStatus.NOT_CREATED; - } - } - - public static TitanOperationStatus handleTitanException(Exception e) { - if (e instanceof TitanConfigurationException) { - return TitanOperationStatus.TITAN_CONFIGURATION; - } - if (e instanceof SchemaViolationException) { - return TitanOperationStatus.TITAN_SCHEMA_VIOLATION; - } - if (e instanceof PermanentLockingException) { - return TitanOperationStatus.TITAN_SCHEMA_VIOLATION; - } - if (e instanceof IDPoolExhaustedException) { - return TitanOperationStatus.GENERAL_ERROR; - } - if (e instanceof InvalidElementException) { - return TitanOperationStatus.INVALID_ELEMENT; - } - if (e instanceof InvalidIDException) { - return TitanOperationStatus.INVALID_ID; - } - if (e instanceof QueryException) { - return TitanOperationStatus.INVALID_QUERY; - } - if (e instanceof ResourceUnavailableException) { - return TitanOperationStatus.RESOURCE_UNAVAILABLE; - } - if (e instanceof IllegalArgumentException) { - // TODO check the error message?? - return TitanOperationStatus.ILLEGAL_ARGUMENT; - } - - return TitanOperationStatus.GENERAL_ERROR; - } - - public boolean getHealth() { - return this.lastHealthState; - } - - private boolean isGraphOpen() { - healthLogger.trace("Invoking Titan health check ..."); - Vertex v = null; - if (graph != null) { - try { - Future future = healthCheckExecutor.submit(healthCallableTask); - v = future.get(this.healthCheckReadTimeout, TimeUnit.SECONDS); - healthLogger.trace("Health Check Node Found... {}", v.property(HEALTH_CHECK)); - graph.tx().commit(); - } catch (Exception e) { - String message = e.getMessage(); - if (message == null) { - message = e.getClass().getName(); - } - logger.error("Titan Health Check Failed. {}", message); - return false; - } - return true; - } else { - return false; - } - } - - - public static void main(String[] args) throws InterruptedException { - TitanGraphClient client = new TitanGraphClient(new DAOTitanStrategy()); - client.createGraph(); - - while (true) { - boolean health = client.isGraphOpen(); - System.err.println("health=" + health); - Thread.sleep(2000); - } - - } - - - private static final String TITAN_HEALTH_CHECK_STR = "titanHealthCheck"; - - private void logAlarm() { - if (lastHealthState) { - BeEcompErrorManager.getInstance().logBeHealthCheckTitanRecovery(TITAN_HEALTH_CHECK_STR); - } else { - BeEcompErrorManager.getInstance().logBeHealthCheckTitanError(TITAN_HEALTH_CHECK_STR); - } - } - - private void createTitanSchema() { - - TitanManagement graphMgt = graph.openManagement(); - TitanGraphIndex index = null; - for (GraphPropertiesDictionary prop : GraphPropertiesDictionary.values()) { - PropertyKey propKey = null; - if (!graphMgt.containsPropertyKey(prop.getProperty())) { - Class clazz = prop.getClazz(); - if (!clazz.isAssignableFrom(ArrayList.class) && !clazz.isAssignableFrom(HashMap.class)) { - propKey = graphMgt.makePropertyKey(prop.getProperty()).dataType(prop.getClazz()).make(); - } - } else { - propKey = graphMgt.getPropertyKey(prop.getProperty()); - } - if (prop.isIndexed()) { - if (!graphMgt.containsGraphIndex(prop.getProperty())) { - if (prop.isUnique()) { - index = graphMgt.buildIndex(prop.getProperty(), Vertex.class).addKey(propKey).unique().buildCompositeIndex(); - // Ensures only one name per vertex - graphMgt.setConsistency(propKey, ConsistencyModifier.LOCK); - // Ensures name uniqueness in the graph - graphMgt.setConsistency(index, ConsistencyModifier.LOCK); - - } else { - graphMgt.buildIndex(prop.getProperty(), Vertex.class).addKey(propKey).buildCompositeIndex(); - } - } - } - } - graphMgt.commit(); - } - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanOperationStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanOperationStatus.java deleted file mode 100644 index dc9ed02fca..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanOperationStatus.java +++ /dev/null @@ -1,26 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.dao.titan; - -public enum TitanOperationStatus { - OK, NOT_CONNECTED, NOT_CREATED, INDEX_CANNOT_BE_CHANGED, NOT_FOUND, MISSING_UNIQUE_ID, MISSING_NODE_LABEL, MULTIPLE_EDGES_WITH_SAME_LABEL, CANNOT_DELETE_NON_LEAF_NODE, MULTIPLE_NODES_WITH_SAME_ID, GRAPH_IS_NOT_AVAILABLE, TITAN_CONFIGURATION, TITAN_SCHEMA_VIOLATION, INVALID_ELEMENT, INVALID_QUERY, INVALID_ID, RESOURCE_UNAVAILABLE, ILLEGAL_ARGUMENT, ALREADY_LOCKED, ALREADY_EXIST, MULTIPLE_CHILDS_WITH_SAME_EDGE, GENERAL_ERROR, MATCH_NOT_FOUND, INVALID_TYPE, PROPERTY_NAME_ALREADY_EXISTS, INVALID_PROPERTY, - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanUtils.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanUtils.java deleted file mode 100644 index 163ef807fb..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.openecomp.sdc.be.dao.titan; - -import com.thinkaurelius.titan.graphdb.query.TitanPredicate; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import static com.thinkaurelius.titan.core.attribute.Contain.NOT_IN; -import static java.util.Collections.emptyMap; -import static org.apache.commons.collections.CollectionUtils.isEmpty; - -public class TitanUtils { - - private TitanUtils() { - } - - public static Map> buildNotInPredicate(String propKey, Collection notInCollection) { - if (isEmpty(notInCollection)) { - return emptyMap(); - } - Map> predicateCriteria = new HashMap<>(); - predicateCriteria.put(propKey, new HashMap.SimpleEntry<>(NOT_IN, notInCollection)); - return predicateCriteria; - } -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/transactions/SimpleTitanTransactionManager.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/transactions/SimpleTitanTransactionManager.java deleted file mode 100644 index 2e5b7ea84c..0000000000 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/transactions/SimpleTitanTransactionManager.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.openecomp.sdc.be.dao.titan.transactions; - -import com.thinkaurelius.titan.core.TitanException; -import com.thinkaurelius.titan.core.TitanGraph; -import org.openecomp.sdc.be.dao.titan.TitanGraphClient; -import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.support.SimpleTransactionStatus; - -import javax.annotation.PostConstruct; - -/** - * Simple transaction manager for the titan database. - * This manager does not deal with transactions propagation and relies on the fact that transactions are automatically created with the first operation on the graph - */ -@Component -public class SimpleTitanTransactionManager implements PlatformTransactionManager { - - private static final Logger log = Logger.getLogger(SimpleTitanTransactionManager.class.getName()); - private final TitanGraphClient titanClient; - private TitanGraph titanGraph; - - public SimpleTitanTransactionManager(TitanGraphClient titanClient) { - this.titanClient = titanClient; - } - - @PostConstruct - public void onInit() { - titanGraph = titanClient.getGraph().left().on(this::onFailingToStartTitan); - } - - @Override - public TransactionStatus getTransaction(TransactionDefinition transactionDefinition) { - log.debug("#getTransaction - returning simple transaction status"); - return new SimpleTransactionStatus(); - } - - @Override - public void commit(TransactionStatus transactionStatus) { - log.debug("#commit - committing transaction"); - try { - titanGraph.tx().commit(); - } catch (TitanException e) { - log.debug("#commit - failed to commit transaction", e); - throw new TransactionSystemException("failed to commit transaction", e); - } - } - - @Override - public void rollback(TransactionStatus transactionStatus) { - log.debug("#rollback - committing transaction"); - try { - titanGraph.tx().rollback(); - } catch (TitanException e) { - log.debug("#rollback - failed to rollback transaction", e); - throw new TransactionSystemException("failed to rollback transaction", e); - } - } - - private TitanGraph onFailingToStartTitan(TitanOperationStatus err) { - log.debug("#onFailingToStartTitan - could not open titan client"); - throw new IllegalStateException("titan could not be initialized: " + err); - } - -} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingTypesConstants.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingTypesConstants.java index b7ca47600a..c6c609b189 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingTypesConstants.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingTypesConstants.java @@ -26,7 +26,7 @@ public interface AuditingTypesConstants { String REPO_KEYSPACE = "sdcrepository"; String AUDIT_KEYSPACE = "sdcaudit"; String COMPONENT_KEYSPACE = "sdccomponent"; - String TITAN_KEYSPACE = "titan"; + String janusGraph_KEYSPACE = "janusgraph"; String USER_ADMIN_EVENT_TYPE = "useradminevent"; String USER_ACCESS_EVENT_TYPE = "useraccessevent"; -- cgit 1.2.3-korg