From 68ee9a62ac3b2d11d8ee4899fddddcfdbb9c7624 Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Mon, 1 Jul 2024 12:14:56 +0200 Subject: [PATCH] implement a mechanism for validating graph stores by injecting hooks --- .../estimation/AlgorithmEstimator.java | 3 ++- .../algorithms/runner/AlgorithmRunner.java | 3 ++- .../runner/AlgorithmRunnerTest.java | 4 ++- ...ityAlgorithmsMutateModeBusinessFacade.java | 8 ++++++ ...lityAlgorithmsStatsModeBusinessFacade.java | 8 ++++++ ...ityAlgorithmsStreamModeBusinessFacade.java | 8 ++++++ ...lityAlgorithmsWriteModeBusinessFacade.java | 8 ++++++ ...ityAlgorithmsMutateModeBusinessFacade.java | 12 +++++++++ ...nityAlgorithmsStatsModeBusinessFacade.java | 12 +++++++++ ...ityAlgorithmsStreamModeBusinessFacade.java | 15 +++++++++++ ...nityAlgorithmsWriteModeBusinessFacade.java | 12 +++++++++ .../AlgorithmProcessingTemplate.java | 2 ++ .../DefaultAlgorithmProcessingTemplate.java | 17 ++++++------ ...efaultAlgorithmProcessingTemplateTest.java | 13 +++++++--- ...ingAlgorithmsMutateModeBusinessFacade.java | 1 + ...dingAlgorithmsStatsModeBusinessFacade.java | 1 + ...ingAlgorithmsStreamModeBusinessFacade.java | 1 + ...dingAlgorithmsWriteModeBusinessFacade.java | 1 + ...ingAlgorithmsMutateModeBusinessFacade.java | 10 +++++++ ...dingAlgorithmsStatsModeBusinessFacade.java | 6 +++++ ...ingAlgorithmsStreamModeBusinessFacade.java | 14 ++++++++++ ...dingAlgorithmsWriteModeBusinessFacade.java | 1 + ...ityAlgorithmsMutateModeBusinessFacade.java | 4 +++ ...rityAlgorithmsStatsModeBusinessFacade.java | 4 +++ ...ityAlgorithmsStreamModeBusinessFacade.java | 4 +++ ...rityAlgorithmsWriteModeBusinessFacade.java | 4 +++ .../loading/GraphStoreCatalogService.java | 19 +++++++++++--- .../PostGraphStoreLoadValidationHook.java | 26 +++++++++++++++++++ .../GraphStoreCatalogServiceGetGraphTest.java | 15 +++++++---- 29 files changed, 214 insertions(+), 22 deletions(-) create mode 100644 core/src/main/java/org/neo4j/gds/core/loading/PostGraphStoreLoadValidationHook.java diff --git a/algo/src/main/java/org/neo4j/gds/algorithms/estimation/AlgorithmEstimator.java b/algo/src/main/java/org/neo4j/gds/algorithms/estimation/AlgorithmEstimator.java index 324c401243..798e954d91 100644 --- a/algo/src/main/java/org/neo4j/gds/algorithms/estimation/AlgorithmEstimator.java +++ b/algo/src/main/java/org/neo4j/gds/algorithms/estimation/AlgorithmEstimator.java @@ -84,7 +84,8 @@ public , C extends AlgoBaseConfig> MemoryEstimateResul config, maybeRelationshipProperty, requestScopedDependencies.getUser(), - requestScopedDependencies.getDatabaseId() + requestScopedDependencies.getDatabaseId(), + Optional.empty() ).graphStore(); dimensions = GraphDimensionsComputer.of(graphStore, config); } else { diff --git a/algo/src/main/java/org/neo4j/gds/algorithms/runner/AlgorithmRunner.java b/algo/src/main/java/org/neo4j/gds/algorithms/runner/AlgorithmRunner.java index c6279feb52..d48df36056 100644 --- a/algo/src/main/java/org/neo4j/gds/algorithms/runner/AlgorithmRunner.java +++ b/algo/src/main/java/org/neo4j/gds/algorithms/runner/AlgorithmRunner.java @@ -86,7 +86,8 @@ public , R, C extends AlgoBaseConfig> AlgorithmComputatio config, relationshipProperty, requestScopedDependencies.getUser(), - requestScopedDependencies.getDatabaseId() + requestScopedDependencies.getDatabaseId(), + Optional.empty() ); var graph = graphResources.graph(); diff --git a/algo/src/test/java/org/neo4j/gds/algorithms/runner/AlgorithmRunnerTest.java b/algo/src/test/java/org/neo4j/gds/algorithms/runner/AlgorithmRunnerTest.java index bf9c14ba9f..15fb05834d 100644 --- a/algo/src/test/java/org/neo4j/gds/algorithms/runner/AlgorithmRunnerTest.java +++ b/algo/src/test/java/org/neo4j/gds/algorithms/runner/AlgorithmRunnerTest.java @@ -33,6 +33,7 @@ import org.neo4j.gds.config.AlgoBaseConfig; import org.neo4j.gds.core.loading.GraphResources; import org.neo4j.gds.core.loading.GraphStoreCatalogService; +import org.neo4j.gds.core.loading.PostGraphStoreLoadValidationHook; import org.neo4j.gds.logging.Log; import org.neo4j.gds.metrics.ExecutionMetric; import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; @@ -157,7 +158,8 @@ public GraphResources getGraphResources( AlgoBaseConfig config, Optional relationshipProperty, User user, - DatabaseId databaseId + DatabaseId databaseId, + Optional> postGraphStoreLoadValidationHooks ) { // this gets called right after the preconditions check // so, we save ourselves trouble and shunt the rest of the method diff --git a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java index bde8283d8d..e203107c9d 100644 --- a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java +++ b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java @@ -76,6 +76,7 @@ public RESULT articleRank( return template.processAlgorithm( graphName, configuration, + Optional.empty(), ArticleRank, estimation::pageRank, graph -> algorithms.articleRank(graph, configuration), @@ -94,6 +95,7 @@ public RESULT betweennessCentrality( return template.processAlgorithm( graphName, configuration, + Optional.empty(), BetweennessCentrality, () -> estimation.betweennessCentrality(configuration), graph -> algorithms.betweennessCentrality(graph, configuration), @@ -112,6 +114,7 @@ public RESULT celf( return template.processAlgorithm( graphName, configuration, + Optional.empty(), CELF, () -> estimation.celf(configuration), graph -> algorithms.celf(graph, configuration), @@ -130,6 +133,7 @@ public RESULT closenessCentrality( return template.processAlgorithm( graphName, configuration, + Optional.empty(), ClosenessCentrality, () -> estimation.closenessCentrality(configuration), graph -> algorithms.closenessCentrality(graph, configuration), @@ -148,6 +152,7 @@ public RESULT degreeCentrality( return template.processAlgorithm( graphName, configuration, + Optional.empty(), DegreeCentrality, () -> estimation.degreeCentrality(configuration), graph -> algorithms.degreeCentrality(graph, configuration), @@ -166,6 +171,7 @@ public RESULT eigenVector( return template.processAlgorithm( graphName, configuration, + Optional.empty(), EigenVector, estimation::pageRank, graph -> algorithms.eigenVector(graph, configuration), @@ -184,6 +190,7 @@ public RESULT harmonicCentrality( return template.processAlgorithm( graphName, configuration, + Optional.empty(), HarmonicCentrality, estimation::harmonicCentrality, graph -> algorithms.harmonicCentrality(graph, configuration), @@ -202,6 +209,7 @@ public RESULT pageRank( return template.processAlgorithm( graphName, configuration, + Optional.empty(), PageRank, estimation::pageRank, graph -> algorithms.pageRank(graph, configuration), diff --git a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStatsModeBusinessFacade.java b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStatsModeBusinessFacade.java index 73cedb7c4a..09c9df26ac 100644 --- a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStatsModeBusinessFacade.java +++ b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStatsModeBusinessFacade.java @@ -66,6 +66,7 @@ public RESULT articleRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ArticleRank, estimationFacade::pageRank, graph -> centralityAlgorithms.articleRank(graph, configuration), @@ -82,6 +83,7 @@ public RESULT betweennessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BetweennessCentrality, () -> estimationFacade.betweennessCentrality(configuration), graph -> centralityAlgorithms.betweennessCentrality(graph, configuration), @@ -98,6 +100,7 @@ public RESULT celf( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), CELF, () -> estimationFacade.celf(configuration), graph -> centralityAlgorithms.celf(graph, configuration), @@ -114,6 +117,7 @@ public RESULT closenessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ClosenessCentrality, () -> estimationFacade.closenessCentrality(configuration), graph -> centralityAlgorithms.closenessCentrality(graph, configuration), @@ -130,6 +134,7 @@ public RESULT degreeCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DegreeCentrality, () -> estimationFacade.degreeCentrality(configuration), graph -> centralityAlgorithms.degreeCentrality(graph, configuration), @@ -146,6 +151,7 @@ public RESULT eigenVector( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), EigenVector, estimationFacade::pageRank, graph -> centralityAlgorithms.eigenVector(graph, configuration), @@ -162,6 +168,7 @@ public RESULT harmonicCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), HarmonicCentrality, estimationFacade::harmonicCentrality, graph -> centralityAlgorithms.harmonicCentrality(graph, configuration), @@ -178,6 +185,7 @@ public RESULT pageRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), PageRank, estimationFacade::pageRank, graph -> centralityAlgorithms.pageRank(graph, configuration), diff --git a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStreamModeBusinessFacade.java b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStreamModeBusinessFacade.java index ada5ef10d4..602cee5e34 100644 --- a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStreamModeBusinessFacade.java +++ b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStreamModeBusinessFacade.java @@ -67,6 +67,7 @@ public RESULT articleRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ArticleRank, estimationFacade::pageRank, graph -> centralityAlgorithms.articleRank(graph, configuration), @@ -83,6 +84,7 @@ public RESULT betweennessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BetweennessCentrality, () -> estimationFacade.betweennessCentrality(configuration), graph -> centralityAlgorithms.betweennessCentrality(graph, configuration), @@ -99,6 +101,7 @@ public RESULT celf( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), CELF, () -> estimationFacade.celf(configuration), graph -> centralityAlgorithms.celf(graph, configuration), @@ -115,6 +118,7 @@ public RESULT closenessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ClosenessCentrality, () -> estimationFacade.closenessCentrality(configuration), graph -> centralityAlgorithms.closenessCentrality(graph, configuration), @@ -131,6 +135,7 @@ public RESULT degreeCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DegreeCentrality, () -> estimationFacade.degreeCentrality(configuration), graph -> centralityAlgorithms.degreeCentrality(graph, configuration), @@ -147,6 +152,7 @@ public RESULT eigenvector( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), EigenVector, estimationFacade::pageRank, graph -> centralityAlgorithms.eigenVector(graph, configuration), @@ -163,6 +169,7 @@ public RESULT harmonicCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), HarmonicCentrality, estimationFacade::harmonicCentrality, graph -> centralityAlgorithms.harmonicCentrality(graph, configuration), @@ -179,6 +186,7 @@ public RESULT pageRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), PageRank, estimationFacade::pageRank, graph -> centralityAlgorithms.pageRank(graph, configuration), diff --git a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsWriteModeBusinessFacade.java index 100e9b9441..98a77567aa 100644 --- a/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsWriteModeBusinessFacade.java +++ b/applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsWriteModeBusinessFacade.java @@ -97,6 +97,7 @@ public RESULT articleRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ArticleRank, estimationFacade::pageRank, graph -> centralityAlgorithms.articleRank(graph, configuration), @@ -115,6 +116,7 @@ public RESULT betweennessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BetweennessCentrality, () -> estimationFacade.betweennessCentrality(configuration), graph -> centralityAlgorithms.betweennessCentrality(graph, configuration), @@ -133,6 +135,7 @@ public RESULT c return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), CELF, () -> estimationFacade.celf(configuration), graph -> centralityAlgorithms.celf(graph, configuration), @@ -151,6 +154,7 @@ public RESULT closenessCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ClosenessCentrality, () -> estimationFacade.closenessCentrality(configuration), graph -> centralityAlgorithms.closenessCentrality(graph, configuration), @@ -169,6 +173,7 @@ public RESULT degreeCentrality( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DegreeCentrality, () -> estimationFacade.degreeCentrality(configuration), graph -> centralityAlgorithms.degreeCentrality(graph, configuration), @@ -187,6 +192,7 @@ public RESULT eigenvector( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), EigenVector, estimationFacade::pageRank, graph -> centralityAlgorithms.eigenVector(graph, configuration), @@ -205,6 +211,7 @@ public RESULT harm return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), HarmonicCentrality, estimationFacade::harmonicCentrality, graph -> centralityAlgorithms.harmonicCentrality(graph, configuration), @@ -223,6 +230,7 @@ public RESULT pageRank( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), PageRank, estimationFacade::pageRank, graph -> centralityAlgorithms.pageRank(graph, configuration), diff --git a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsMutateModeBusinessFacade.java b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsMutateModeBusinessFacade.java index c566f1ff24..d2b0aa8ef2 100644 --- a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsMutateModeBusinessFacade.java +++ b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsMutateModeBusinessFacade.java @@ -94,6 +94,7 @@ public RESULT approximateMaximumKCut( return template.processAlgorithm( graphName, configuration, + Optional.empty(), ApproximateMaximumKCut, () -> estimation.approximateMaximumKCut(configuration), graph -> algorithms.approximateMaximumKCut(graph, configuration), @@ -112,6 +113,7 @@ public RESULT k1Coloring( return template.processAlgorithm( graphName, configuration, + Optional.empty(), K1Coloring, estimation::k1Coloring, graph -> algorithms.k1Coloring(graph, configuration), @@ -130,6 +132,7 @@ public RESULT kCore( return template.processAlgorithm( graphName, configuration, + Optional.empty(), KCore, estimation::kCore, graph -> algorithms.kCore(graph, configuration), @@ -148,6 +151,7 @@ public RESULT kMeans( return template.processAlgorithm( graphName, configuration, + Optional.empty(), KMeans, () -> estimation.kMeans(configuration), graph -> algorithms.kMeans(graph, configuration), @@ -166,6 +170,7 @@ public RESULT labelPropagation( return template.processAlgorithm( graphName, configuration, + Optional.empty(), LabelPropagation, estimation::labelPropagation, graph -> algorithms.labelPropagation(graph, configuration), @@ -184,6 +189,7 @@ public RESULT lcc( return template.processAlgorithm( graphName, configuration, + Optional.empty(), LCC, () -> estimation.lcc(configuration), graph -> algorithms.lcc(graph, configuration), @@ -202,6 +208,7 @@ public RESULT leiden( return template.processAlgorithm( graphName, configuration, + Optional.empty(), Leiden, () -> estimation.leiden(configuration), graph -> algorithms.leiden(graph, configuration), @@ -220,6 +227,7 @@ public RESULT louvain( return template.processAlgorithm( graphName, configuration, + Optional.empty(), Louvain, () -> estimation.louvain(configuration), graph -> algorithms.louvain(graph, configuration), @@ -238,6 +246,7 @@ public RESULT modularityOptimization( return template.processAlgorithm( graphName, configuration, + Optional.empty(), ModularityOptimization, estimation::modularityOptimization, graph -> algorithms.modularityOptimization(graph, configuration), @@ -256,6 +265,7 @@ public RESULT scc( return template.processAlgorithm( graphName, configuration, + Optional.empty(), SCC, estimation::scc, graph -> algorithms.scc(graph, configuration), @@ -274,6 +284,7 @@ public RESULT triangleCount( return template.processAlgorithm( graphName, configuration, + Optional.empty(), TriangleCount, estimation::triangleCount, graph -> algorithms.triangleCount(graph, configuration), @@ -292,6 +303,7 @@ public RESULT wcc( return template.processAlgorithm( graphName, configuration, + Optional.empty(), WCC, () -> estimation.wcc(configuration), graph -> algorithms.wcc(graph, configuration), diff --git a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStatsModeBusinessFacade.java b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStatsModeBusinessFacade.java index f9fb7e7a6c..166d208b03 100644 --- a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStatsModeBusinessFacade.java +++ b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStatsModeBusinessFacade.java @@ -85,6 +85,7 @@ public RESULT k1Coloring( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), K1Coloring, estimationFacade::k1Coloring, graph -> communityAlgorithms.k1Coloring(graph, configuration), @@ -101,6 +102,7 @@ public RESULT kCore( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KCore, estimationFacade::kCore, graph -> communityAlgorithms.kCore(graph, configuration), @@ -117,6 +119,7 @@ public RESULT kMeans( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KMeans, () -> estimationFacade.kMeans(configuration), graph -> communityAlgorithms.kMeans(graph, configuration), @@ -133,6 +136,7 @@ public RESULT labelPropagation( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelPropagation, estimationFacade::labelPropagation, graph -> communityAlgorithms.labelPropagation(graph, configuration), @@ -149,6 +153,7 @@ public RESULT lcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LCC, () -> estimationFacade.lcc(configuration), graph -> communityAlgorithms.lcc(graph, configuration), @@ -165,6 +170,7 @@ public RESULT leiden( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Leiden, () -> estimationFacade.leiden(configuration), graph -> communityAlgorithms.leiden(graph, configuration), @@ -181,6 +187,7 @@ public RESULT louvain( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Louvain, () -> estimationFacade.louvain(configuration), graph -> communityAlgorithms.louvain(graph, configuration), @@ -197,6 +204,7 @@ public RESULT modularity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Modularity, estimationFacade::modularity, graph -> communityAlgorithms.modularity(graph, configuration), @@ -213,6 +221,7 @@ public RESULT modularityOptimization( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ModularityOptimization, estimationFacade::modularityOptimization, graph -> communityAlgorithms.modularityOptimization(graph, configuration), @@ -229,6 +238,7 @@ public RESULT scc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SCC, estimationFacade::scc, graph -> communityAlgorithms.scc(graph, configuration), @@ -245,6 +255,7 @@ public RESULT triangleCount( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), TriangleCount, estimationFacade::triangleCount, graph -> communityAlgorithms.triangleCount(graph, configuration), @@ -261,6 +272,7 @@ public RESULT wcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), WCC, () -> estimationFacade.wcc(configuration), graph -> communityAlgorithms.wcc(graph, configuration), diff --git a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStreamModeBusinessFacade.java b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStreamModeBusinessFacade.java index 4a15316266..088fd53fc7 100644 --- a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStreamModeBusinessFacade.java +++ b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsStreamModeBusinessFacade.java @@ -95,6 +95,7 @@ public RESULT approximateMaximumKCut( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ApproximateMaximumKCut, () -> estimationFacade.approximateMaximumKCut(configuration), graph -> algorithms.approximateMaximumKCut(graph, configuration), @@ -111,6 +112,7 @@ public RESULT conductance( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Conductance, estimationFacade::conductance, graph -> algorithms.conductance(graph, configuration), @@ -127,6 +129,7 @@ public RESULT k1Coloring( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), K1Coloring, estimationFacade::k1Coloring, graph -> algorithms.k1Coloring(graph, configuration), @@ -143,6 +146,7 @@ public RESULT kCore( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KCore, estimationFacade::kCore, graph -> algorithms.kCore(graph, configuration), @@ -159,6 +163,7 @@ public RESULT kMeans( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KMeans, () -> estimationFacade.kMeans(configuration), graph -> algorithms.kMeans(graph, configuration), @@ -175,6 +180,7 @@ public RESULT labelPropagation( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelPropagation, estimationFacade::labelPropagation, graph -> algorithms.labelPropagation(graph, configuration), @@ -191,6 +197,7 @@ public RESULT lcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LCC, () -> estimationFacade.lcc(configuration), graph -> algorithms.lcc(graph, configuration), @@ -207,6 +214,7 @@ public RESULT leiden( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Leiden, () -> estimationFacade.leiden(configuration), graph -> algorithms.leiden(graph, configuration), @@ -223,6 +231,7 @@ public RESULT louvain( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Louvain, () -> estimationFacade.louvain(configuration), graph -> algorithms.louvain(graph, configuration), @@ -239,6 +248,7 @@ public RESULT modularity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Modularity, estimationFacade::modularity, graph -> algorithms.modularity(graph, configuration), @@ -255,6 +265,7 @@ public RESULT modularityOptimization( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ModularityOptimization, estimationFacade::modularityOptimization, graph -> algorithms.modularityOptimization(graph, configuration), @@ -271,6 +282,7 @@ public RESULT scc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SCC, estimationFacade::scc, graph -> algorithms.scc(graph, configuration), @@ -287,6 +299,7 @@ public RESULT triangleCount( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), TriangleCount, estimationFacade::triangleCount, graph -> algorithms.triangleCount(graph, configuration), @@ -303,6 +316,7 @@ public RESULT triangles( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Triangles, estimationFacade::triangles, graph -> algorithms.triangles(graph, configuration), @@ -319,6 +333,7 @@ public RESULT wcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), WCC, () -> estimationFacade.wcc(configuration), graph -> algorithms.wcc(graph, configuration), diff --git a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsWriteModeBusinessFacade.java index b0c69c0fdd..f019fa2973 100644 --- a/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsWriteModeBusinessFacade.java +++ b/applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsWriteModeBusinessFacade.java @@ -115,6 +115,7 @@ public RESULT k1Coloring( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), K1Coloring, estimationFacade::k1Coloring, graph -> algorithms.k1Coloring(graph, configuration), @@ -133,6 +134,7 @@ public RESULT kCore( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KCore, estimationFacade::kCore, graph -> algorithms.kCore(graph, configuration), @@ -151,6 +153,7 @@ public RESULT kMeans( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KMeans, () -> estimationFacade.kMeans(configuration), graph -> algorithms.kMeans(graph, configuration), @@ -169,6 +172,7 @@ public RESULT labelPropagation( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelPropagation, estimationFacade::labelPropagation, graph -> algorithms.labelPropagation(graph, configuration), @@ -187,6 +191,7 @@ public RESULT lcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LCC, () -> estimationFacade.lcc(configuration), graph -> algorithms.lcc(graph, configuration), @@ -205,6 +210,7 @@ public RESULT leiden( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Leiden, () -> estimationFacade.leiden(configuration), graph -> algorithms.leiden(graph, configuration), @@ -223,6 +229,7 @@ public RESULT louvain( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Louvain, () -> estimationFacade.louvain(configuration), graph -> algorithms.louvain(graph, configuration), @@ -241,6 +248,7 @@ public RESULT modularityOptimization( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), ModularityOptimization, estimationFacade::modularityOptimization, graph -> algorithms.modularityOptimization(graph, configuration), @@ -259,6 +267,7 @@ public RESULT scc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SCC, estimationFacade::scc, graph -> algorithms.scc(graph, configuration), @@ -277,6 +286,7 @@ public RESULT sccAlpha( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SCC, estimationFacade::scc, graph -> algorithms.scc(graph, configuration), @@ -295,6 +305,7 @@ public RESULT triangleCount( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), TriangleCount, estimationFacade::triangleCount, graph -> algorithms.triangleCount(graph, configuration), @@ -313,6 +324,7 @@ public RESULT wcc( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), WCC, () -> estimationFacade.wcc(configuration), graph -> algorithms.wcc(graph, configuration), diff --git a/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/AlgorithmProcessingTemplate.java b/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/AlgorithmProcessingTemplate.java index 3f66f0ab45..1c27e9d4bb 100644 --- a/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/AlgorithmProcessingTemplate.java +++ b/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/AlgorithmProcessingTemplate.java @@ -22,6 +22,7 @@ import org.neo4j.gds.api.GraphName; import org.neo4j.gds.applications.algorithms.metadata.LabelForProgressTracking; import org.neo4j.gds.config.AlgoBaseConfig; +import org.neo4j.gds.core.loading.PostGraphStoreLoadValidationHook; import org.neo4j.gds.mem.MemoryEstimation; import java.util.Optional; @@ -57,6 +58,7 @@ public interface AlgorithmProcessingTemplate { RESULT_TO_CALLER processAlgorithm( GraphName graphName, CONFIGURATION configuration, + Optional> postGraphStoreLoadValidationHooks, LabelForProgressTracking label, Supplier estimationFactory, AlgorithmComputation algorithmComputation, diff --git a/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplate.java b/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplate.java index e40d38d636..39f9a80d27 100644 --- a/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplate.java +++ b/applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplate.java @@ -28,6 +28,7 @@ import org.neo4j.gds.config.RelationshipWeightConfig; import org.neo4j.gds.core.loading.GraphResources; import org.neo4j.gds.core.loading.GraphStoreCatalogService; +import org.neo4j.gds.core.loading.PostGraphStoreLoadValidationHook; import org.neo4j.gds.core.utils.ProgressTimer; import org.neo4j.gds.core.utils.progress.JobId; import org.neo4j.gds.logging.Log; @@ -65,6 +66,7 @@ public DefaultAlgorithmProcessingTemplate( public RESULT_TO_CALLER processAlgorithm( GraphName graphName, CONFIGURATION configuration, + Optional> postGraphStoreLoadValidationHooks, LabelForProgressTracking label, Supplier estimationFactory, AlgorithmComputation algorithmComputation, @@ -77,7 +79,8 @@ public GraphResources graphLoadAndValidationWithTiming( AlgorithmProcessingTimingsBuilder timingsBuilder, GraphName graphName, - CONFIGURATION configuration + CONFIGURATION configuration, + Optional> postGraphStoreLoadValidationHooks ) { try (ProgressTimer ignored = ProgressTimer.start(timingsBuilder::withPreProcessingMillis)) { // tee up the graph we want to work on var relationshipProperty = extractRelationshipProperty(configuration); - var graphResources = graphStoreCatalogService.getGraphResources( + return graphStoreCatalogService.getGraphResources( graphName, configuration, relationshipProperty, requestScopedDependencies.getUser(), - requestScopedDependencies.getDatabaseId() + requestScopedDependencies.getDatabaseId(), + postGraphStoreLoadValidationHooks ); - - // ValidationConfiguration post-load stuff would go here - - return graphResources; } } diff --git a/applications/algorithms/machinery/src/test/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplateTest.java b/applications/algorithms/machinery/src/test/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplateTest.java index 0d6847d50c..0cb665f96a 100644 --- a/applications/algorithms/machinery/src/test/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplateTest.java +++ b/applications/algorithms/machinery/src/test/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplateTest.java @@ -30,6 +30,7 @@ import org.neo4j.gds.config.AlgoBaseConfig; import org.neo4j.gds.core.loading.GraphResources; import org.neo4j.gds.core.loading.GraphStoreCatalogService; +import org.neo4j.gds.core.loading.PostGraphStoreLoadValidationHook; import org.neo4j.gds.core.utils.progress.JobId; import org.neo4j.gds.metrics.ExecutionMetric; import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; @@ -74,7 +75,8 @@ void shouldProcessStreamAlgorithm() { configuration, Optional.empty(), user, - databaseId + databaseId, + Optional.empty() )).thenReturn(new GraphResources(graphStore, graph, ResultStore.EMPTY)); // We need it to not be null :shrug: @@ -109,6 +111,7 @@ public Stream build( var resultStream = algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Dijkstra, null, computation, @@ -150,7 +153,8 @@ void shouldProcessMutateOrWriteAlgorithm() { configuration, Optional.empty(), user, - databaseId + databaseId, + Optional.empty() )).thenReturn(new GraphResources(graphStore, graph, ResultStore.EMPTY)); var pathFindingResult = mock(ExampleResult.class); @@ -197,6 +201,7 @@ public Long execute( var relationshipsWritten = algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KNN, null, computation, @@ -220,7 +225,8 @@ void shouldDoTimingsAndCounts() { GraphResources graphLoadAndValidationWithTiming( AlgorithmProcessingTimingsBuilder timingsBuilder, GraphName graphName, - CONFIGURATION configuration + CONFIGURATION configuration, + Optional> postGraphStoreLoadValidationHooks ) { timingsBuilder.withPreProcessingMillis(23); return new GraphResources(null, mock(Graph.class), null); @@ -280,6 +286,7 @@ public Map build( var resultMap = algorithmProcessingTemplate.processAlgorithm( null, new ExampleConfiguration(), + Optional.empty(), null, null, null, diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsMutateModeBusinessFacade.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsMutateModeBusinessFacade.java index 0765dd0c9b..b21af12e8c 100644 --- a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsMutateModeBusinessFacade.java +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsMutateModeBusinessFacade.java @@ -59,6 +59,7 @@ public RESULT fastRP( return template.processAlgorithm( graphName, configuration, + Optional.empty(), FastRP, () -> estimation.fastRP(configuration), graph -> algorithms.fastRP(graph, configuration), diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStatsModeBusinessFacade.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStatsModeBusinessFacade.java index 3533e6018c..021f13e141 100644 --- a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStatsModeBusinessFacade.java +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStatsModeBusinessFacade.java @@ -52,6 +52,7 @@ public RESULT fastRP( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FastRP, () -> estimationFacade.fastRP(configuration), graph -> algorithms.fastRP(graph, configuration), diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStreamModeBusinessFacade.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStreamModeBusinessFacade.java index 091f86ee00..aaca93915a 100644 --- a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStreamModeBusinessFacade.java +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsStreamModeBusinessFacade.java @@ -52,6 +52,7 @@ public RESULT fastRP( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FastRP, () -> estimationFacade.fastRP(configuration), graph -> algorithms.fastRP(graph, configuration), diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java index 1ac725a91a..5704c3cebd 100644 --- a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java @@ -82,6 +82,7 @@ public RESULT fastRP( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FastRP, () -> estimationFacade.fastRP(configuration), graph -> algorithms.fastRP(graph, configuration), diff --git a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsMutateModeBusinessFacade.java b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsMutateModeBusinessFacade.java index 509dfba961..ef16ab329f 100644 --- a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsMutateModeBusinessFacade.java +++ b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsMutateModeBusinessFacade.java @@ -82,6 +82,7 @@ public RESULT bellmanFord( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BellmanFord, () -> estimationFacade.bellmanFord(configuration), graph -> pathFindingAlgorithms.bellmanFord(graph, configuration), @@ -101,6 +102,7 @@ public RESULT breadthFirstSearch( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BFS, estimationFacade::breadthFirstSearch, graph -> pathFindingAlgorithms.breadthFirstSearch(graph, configuration), @@ -119,6 +121,7 @@ public RESULT deltaStepping( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DeltaStepping, estimationFacade::deltaStepping, graph -> pathFindingAlgorithms.deltaStepping(graph, configuration), @@ -138,6 +141,7 @@ public RESULT depthFirstSearch( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DFS, estimationFacade::depthFirstSearch, graph -> pathFindingAlgorithms.depthFirstSearch(graph, configuration), @@ -156,6 +160,7 @@ public RESULT singlePairShortestPathAStar( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), AStar, estimationFacade::singlePairShortestPathAStar, graph -> pathFindingAlgorithms.singlePairShortestPathAStar(graph, configuration), @@ -174,6 +179,7 @@ public RESULT singlePairShortestPathDijkstra( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Dijkstra, () -> estimationFacade.singlePairShortestPathDijkstra(configuration), graph -> pathFindingAlgorithms.singlePairShortestPathDijkstra(graph, configuration), @@ -192,6 +198,7 @@ public RESULT singlePairShortestPathYens( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Yens, () -> estimationFacade.singlePairShortestPathYens(configuration), graph -> pathFindingAlgorithms.singlePairShortestPathYens(graph, configuration), @@ -210,6 +217,7 @@ public RESULT singleSourceShortestPathDijkstra( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SingleSourceDijkstra, () -> estimationFacade.singleSourceShortestPathDijkstra(configuration), graph -> pathFindingAlgorithms.singleSourceShortestPathDijkstra(graph, configuration), @@ -228,6 +236,7 @@ public RESULT spanningTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelForProgressTracking.SpanningTree, estimationFacade::spanningTree, graph -> pathFindingAlgorithms.spanningTree(graph, configuration), @@ -246,6 +255,7 @@ public RESULT steinerTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SteinerTree, () -> estimationFacade.steinerTree(configuration), graph -> pathFindingAlgorithms.steinerTree(graph, configuration), diff --git a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStatsModeBusinessFacade.java b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStatsModeBusinessFacade.java index 4248f879f3..5489fe4a9c 100644 --- a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStatsModeBusinessFacade.java +++ b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStatsModeBusinessFacade.java @@ -68,6 +68,7 @@ public RESULT bellmanFord( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BellmanFord, () -> estimationFacade.bellmanFord(configuration), graph -> pathFindingAlgorithms.bellmanFord(graph, configuration), @@ -84,6 +85,7 @@ public RESULT breadthFirstSearch( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BFS, estimationFacade::breadthFirstSearch, graph -> pathFindingAlgorithms.breadthFirstSearch(graph, configuration), @@ -100,6 +102,7 @@ public RESULT deltaStepping( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DeltaStepping, estimationFacade::deltaStepping, graph -> pathFindingAlgorithms.deltaStepping(graph, configuration), @@ -116,6 +119,7 @@ public RESULT randomWalk( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), RandomWalk, () -> estimationFacade.randomWalk(configuration), graph -> pathFindingAlgorithms.randomWalk(graph, configuration), @@ -132,6 +136,7 @@ public RESULT spanningTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelForProgressTracking.SpanningTree, estimationFacade::spanningTree, graph -> pathFindingAlgorithms.spanningTree(graph, configuration), @@ -148,6 +153,7 @@ public RESULT steinerTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SteinerTree, () -> estimationFacade.steinerTree(configuration), graph -> pathFindingAlgorithms.steinerTree(graph, configuration), diff --git a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStreamModeBusinessFacade.java b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStreamModeBusinessFacade.java index a7d8facfb8..5c2d2a5337 100644 --- a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStreamModeBusinessFacade.java +++ b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsStreamModeBusinessFacade.java @@ -90,6 +90,7 @@ public RESULT allShortestPaths( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), AllShortestPaths, estimationFacade::allShortestPaths, graph -> pathFindingAlgorithms.allShortestPaths(graph, configuration), @@ -106,6 +107,7 @@ public RESULT bellmanFord( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BellmanFord, () -> estimationFacade.bellmanFord(configuration), graph -> pathFindingAlgorithms.bellmanFord(graph, configuration), @@ -122,6 +124,7 @@ public RESULT breadthFirstSearch( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), BFS, estimationFacade::breadthFirstSearch, graph -> pathFindingAlgorithms.breadthFirstSearch(graph, configuration), @@ -138,6 +141,7 @@ public RESULT deltaStepping( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DeltaStepping, estimationFacade::deltaStepping, graph -> pathFindingAlgorithms.deltaStepping(graph, configuration), @@ -154,6 +158,7 @@ public RESULT depthFirstSearch( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), DFS, estimationFacade::depthFirstSearch, graph -> pathFindingAlgorithms.depthFirstSearch(graph, configuration), @@ -170,6 +175,7 @@ public RESULT longestPath( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LongestPath, estimationFacade::longestPath, graph -> pathFindingAlgorithms.longestPath(graph, configuration), @@ -186,6 +192,7 @@ public RESULT randomWalk( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), RandomWalk, () -> estimationFacade.randomWalk(configuration), graph -> pathFindingAlgorithms.randomWalk(graph, configuration), @@ -202,6 +209,7 @@ public RESULT singlePairShortestPathAStar( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), AStar, estimationFacade::singlePairShortestPathAStar, graph -> pathFindingAlgorithms.singlePairShortestPathAStar(graph, configuration), @@ -218,6 +226,7 @@ public RESULT singlePairShortestPathDijkstra( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Dijkstra, () -> estimationFacade.singlePairShortestPathDijkstra(configuration), graph -> pathFindingAlgorithms.singlePairShortestPathDijkstra(graph, configuration), @@ -234,6 +243,7 @@ public RESULT singlePairShortestPathYens( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), Yens, () -> estimationFacade.singlePairShortestPathYens(configuration), graph -> pathFindingAlgorithms.singlePairShortestPathYens(graph, configuration), @@ -250,6 +260,7 @@ public RESULT singleSourceShortestPathDijkstra( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SingleSourceDijkstra, () -> estimationFacade.singleSourceShortestPathDijkstra(configuration), graph -> pathFindingAlgorithms.singleSourceShortestPathDijkstra(graph, configuration), @@ -266,6 +277,7 @@ public RESULT spanningTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), LabelForProgressTracking.SpanningTree, estimationFacade::spanningTree, graph -> pathFindingAlgorithms.spanningTree(graph, configuration), @@ -282,6 +294,7 @@ public RESULT steinerTree( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), SteinerTree, () -> estimationFacade.steinerTree(configuration), graph -> pathFindingAlgorithms.steinerTree(graph, configuration), @@ -298,6 +311,7 @@ public RESULT topologicalSort( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), TopologicalSort, estimationFacade::topologicalSort, graph -> pathFindingAlgorithms.topologicalSort(graph, configuration), diff --git a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsWriteModeBusinessFacade.java index 29354b0fda..6ba27a9e24 100644 --- a/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsWriteModeBusinessFacade.java +++ b/applications/algorithms/path-finding/src/main/java/org/neo4j/gds/applications/algorithms/pathfinding/PathFindingAlgorithmsWriteModeBusinessFacade.java @@ -292,6 +292,7 @@ private RESULT filteredKnn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredKNN, () -> estimationFacade.filteredKnn(configuration), graph -> similarityAlgorithms.filteredKnn(graph, configuration), @@ -92,6 +93,7 @@ public RESULT filteredNodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredNodeSimilarity, () -> estimationFacade.filteredNodeSimilarity(configuration), graph -> similarityAlgorithms.filteredNodeSimilarity(graph, configuration), @@ -111,6 +113,7 @@ public RESULT knn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KNN, () -> estimationFacade.knn(configuration), graph -> similarityAlgorithms.knn(graph, configuration), @@ -130,6 +133,7 @@ public RESULT nodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), NodeSimilarity, () -> estimationFacade.nodeSimilarity(configuration), graph -> similarityAlgorithms.nodeSimilarity(graph, configuration), diff --git a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStatsModeBusinessFacade.java b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStatsModeBusinessFacade.java index b63657e6bf..acaef83a5d 100644 --- a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStatsModeBusinessFacade.java +++ b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStatsModeBusinessFacade.java @@ -60,6 +60,7 @@ public RESULT filteredKnn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredKNN, () -> estimationFacade.filteredKnn(configuration), graph -> similarityAlgorithms.filteredKnn(graph, configuration), @@ -76,6 +77,7 @@ public RESULT filteredNodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredNodeSimilarity, () -> estimationFacade.filteredNodeSimilarity(configuration), graph -> similarityAlgorithms.filteredNodeSimilarity(graph, configuration), @@ -92,6 +94,7 @@ public RESULT knn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KNN, () -> estimationFacade.knn(configuration), graph -> similarityAlgorithms.knn(graph, configuration), @@ -108,6 +111,7 @@ public RESULT nodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), NodeSimilarity, () -> estimationFacade.nodeSimilarity(configuration), graph -> similarityAlgorithms.nodeSimilarity(graph, configuration), diff --git a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStreamModeBusinessFacade.java b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStreamModeBusinessFacade.java index 3dc106ca80..2d75b88eab 100644 --- a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStreamModeBusinessFacade.java +++ b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStreamModeBusinessFacade.java @@ -60,6 +60,7 @@ public RESULT filteredKnn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredKNN, () -> estimationFacade.filteredKnn(configuration), graph -> similarityAlgorithms.filteredKnn(graph, configuration), @@ -76,6 +77,7 @@ public RESULT filteredNodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredNodeSimilarity, () -> estimationFacade.filteredNodeSimilarity(configuration), graph -> similarityAlgorithms.filteredNodeSimilarity(graph, configuration), @@ -92,6 +94,7 @@ public RESULT knn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KNN, () -> estimationFacade.knn(configuration), graph -> similarityAlgorithms.knn(graph, configuration), @@ -108,6 +111,7 @@ public RESULT nodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), NodeSimilarity, () -> estimationFacade.nodeSimilarity(configuration), graph -> similarityAlgorithms.nodeSimilarity(graph, configuration), diff --git a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsWriteModeBusinessFacade.java index a059f3515a..cc5952a2dd 100644 --- a/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsWriteModeBusinessFacade.java +++ b/applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsWriteModeBusinessFacade.java @@ -74,6 +74,7 @@ public RESULT filteredKnn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredKNN, () -> estimationFacade.filteredKnn(configuration), graph -> similarityAlgorithms.filteredKnn(graph, configuration), @@ -97,6 +98,7 @@ public RESULT filteredNodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), FilteredNodeSimilarity, () -> estimationFacade.filteredNodeSimilarity(configuration), graph -> similarityAlgorithms.filteredNodeSimilarity(graph, configuration), @@ -120,6 +122,7 @@ public RESULT knn( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), KNN, () -> estimationFacade.knn(configuration), graph -> similarityAlgorithms.knn(graph, configuration), @@ -143,6 +146,7 @@ public RESULT nodeSimilarity( return algorithmProcessingTemplate.processAlgorithm( graphName, configuration, + Optional.empty(), NodeSimilarity, () -> estimationFacade.nodeSimilarity(configuration), graph -> similarityAlgorithms.nodeSimilarity(graph, configuration), diff --git a/core/src/main/java/org/neo4j/gds/core/loading/GraphStoreCatalogService.java b/core/src/main/java/org/neo4j/gds/core/loading/GraphStoreCatalogService.java index 09521feb66..ba01fde15a 100644 --- a/core/src/main/java/org/neo4j/gds/core/loading/GraphStoreCatalogService.java +++ b/core/src/main/java/org/neo4j/gds/core/loading/GraphStoreCatalogService.java @@ -72,11 +72,13 @@ public GraphResources getGraphResources( AlgoBaseConfig config, Optional relationshipProperty, User user, - DatabaseId databaseId + DatabaseId databaseId, + Optional> postGraphStoreLoadValidationHooks ) { var graphStoreCatalogEntry = getGraphStoreCatalogEntry(graphName, config, user, databaseId); var graphStore = graphStoreCatalogEntry.graphStore(); - // TODO: Maybe validation of the graph store, where do this happen? Is this the right place? + + postGraphStoreLoadValidationHooks.ifPresent(hooks -> validateGraphStore(graphStore, hooks)); var nodeLabels = config.nodeLabelsFilter(); @@ -99,6 +101,17 @@ public GraphResources getGraphResources( return new GraphResources(graphStore, graph, graphStoreCatalogEntry.resultStore()); } + /** + * Some use cases need special validation. We do this right after loading. + * + * @throws java.lang.IllegalArgumentException if the graph store did not conform to desired invariants + */ + private void validateGraphStore(GraphStore graphStore, Iterable validationHooks) { + for (PostGraphStoreLoadValidationHook hook : validationHooks) { + hook.onGraphStoreLoaded(graphStore); + } + } + /** * @deprecated Push RequestScopedDependencies down and use it instead of database id + user parameters */ @@ -129,7 +142,7 @@ public void ensureGraphDoesNotExist(User user, DatabaseId databaseId, GraphName * @throws java.lang.IllegalArgumentException if graph does not exist in graph catalog */ public void ensureGraphExists(User user, DatabaseId databaseId, GraphName graphName) { - if (! graphExists(user, databaseId, graphName)) { + if (!graphExists(user, databaseId, graphName)) { String message = formatWithLocale( "The graph '%s' does not exist.", graphName diff --git a/core/src/main/java/org/neo4j/gds/core/loading/PostGraphStoreLoadValidationHook.java b/core/src/main/java/org/neo4j/gds/core/loading/PostGraphStoreLoadValidationHook.java new file mode 100644 index 0000000000..ce115e0b05 --- /dev/null +++ b/core/src/main/java/org/neo4j/gds/core/loading/PostGraphStoreLoadValidationHook.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gds.core.loading; + +import org.neo4j.gds.api.GraphStore; + +public interface PostGraphStoreLoadValidationHook { + void onGraphStoreLoaded(GraphStore graphStore); +} diff --git a/core/src/test/java/org/neo4j/gds/core/loading/GraphStoreCatalogServiceGetGraphTest.java b/core/src/test/java/org/neo4j/gds/core/loading/GraphStoreCatalogServiceGetGraphTest.java index 42b11d0bc3..0f6baa43d0 100644 --- a/core/src/test/java/org/neo4j/gds/core/loading/GraphStoreCatalogServiceGetGraphTest.java +++ b/core/src/test/java/org/neo4j/gds/core/loading/GraphStoreCatalogServiceGetGraphTest.java @@ -82,7 +82,8 @@ void shouldWorkWithoutAnyFilters(SoftAssertions assertions) { configMock, Optional.empty(), new User("bogusUser", false), - DatabaseId.EMPTY + DatabaseId.EMPTY, + Optional.empty() ); assertThat(graphResources.graphStore()).isSameAs(graphStore); @@ -125,7 +126,8 @@ void shouldWorkWithNodeLabels(SoftAssertions assertions) { configMock, Optional.empty(), new User("bogusUser", false), - DatabaseId.EMPTY + DatabaseId.EMPTY, + Optional.empty() ); assertThat(graphResources.graphStore()).isSameAs(graphStore); @@ -168,7 +170,8 @@ void shouldWorkWithRelationshipTypes(SoftAssertions assertions) { configMock, Optional.empty(), new User("bogusUser", false), - DatabaseId.EMPTY + DatabaseId.EMPTY, + Optional.empty() ); assertThat(graphResources.graphStore()).isSameAs(graphStore); @@ -212,7 +215,8 @@ void shouldWorkWithNodeLabelsAndRelationshipTypes(SoftAssertions assertions) { configMock, Optional.empty(), new User("bogusUser", false), - DatabaseId.EMPTY + DatabaseId.EMPTY, + Optional.empty() ); assertThat(graphResources.graphStore()).isSameAs(graphStore); @@ -257,7 +261,8 @@ void shouldReturnGraphWithNoRelationshipsForEmptyRelationshipTypeFilter(SoftAsse configMock, Optional.empty(), new User("bogusUser", false), - DatabaseId.EMPTY + DatabaseId.EMPTY, + Optional.empty() ); assertThat(graphResources.graphStore()).isSameAs(graphStore);