From 8e29a46c2d14c97c355f009707d7d2cbe50a58f9 Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Mon, 5 Aug 2024 11:50:43 +0200 Subject: [PATCH 1/7] add modules for graph catalog and model catalog, and populate them --- alpha/alpha-proc/build.gradle | 1 + .../org/neo4j/gds/userlog/UserLogProc.java | 2 +- .../neo4j/gds/userlog/UserLogProcTest.java | 6 +- applications/facade/build.gradle | 1 + .../gds/applications/ApplicationsFacade.java | 79 +++++++++++++------ .../ApplicationsFacadeBuilder.java | 24 ++++-- ...a => DefaultGraphCatalogApplications.java} | 12 ++- ...faultGraphCatalogApplicationsBuilder.java} | 53 ++++++------- ...ade.java => GraphCatalogApplications.java} | 2 +- ... DefaultGraphCatalogApplicationsTest.java} | 18 ++--- applications/model-catalog/build.gradle | 13 +++ .../DefaultModelCatalogApplications.java | 51 ++++++++++++ .../ModelCatalogApplications.java | 24 ++++++ .../modelcatalog}/ModelExistsResult.java | 3 +- .../applications/modelcatalog/ModelName.java | 60 ++++++++++++++ proc/catalog/build.gradle | 7 +- .../gds/beta/generator/GraphGenerateProc.java | 2 +- .../catalog/GraphDropGraphPropertiesProc.java | 2 +- .../catalog/GraphDropNodePropertiesProc.java | 4 +- .../org/neo4j/gds/catalog/GraphDropProc.java | 2 +- .../catalog/GraphDropRelationshipProc.java | 4 +- .../neo4j/gds/catalog/GraphExistsFunc.java | 2 +- .../neo4j/gds/catalog/GraphExistsProc.java | 2 +- .../neo4j/gds/catalog/GraphFilterProc.java | 2 +- .../org/neo4j/gds/catalog/GraphListProc.java | 4 +- .../gds/catalog/GraphMemoryUsageProc.java | 2 +- .../gds/catalog/GraphMutateNodeLabelProc.java | 2 +- .../neo4j/gds/catalog/GraphProjectProc.java | 10 +-- .../neo4j/gds/catalog/GraphSampleProc.java | 6 +- .../GraphStreamGraphPropertiesProc.java | 2 +- .../GraphStreamNodePropertiesProc.java | 8 +- ...GraphStreamRelationshipPropertiesProc.java | 8 +- .../catalog/GraphStreamRelationshipsProc.java | 4 +- .../gds/catalog/GraphWriteNodeLabelProc.java | 4 +- .../catalog/GraphWriteNodePropertiesProc.java | 4 +- .../catalog/GraphWriteRelationshipProc.java | 4 +- .../GraphWriteRelationshipPropertiesProc.java | 2 +- .../gds/model/catalog/ModelExistsProc.java | 30 +++---- .../neo4j/gds/catalog/GraphDropProcTest.java | 6 +- .../neo4j/gds/catalog/GraphListProcTest.java | 6 +- .../catalog/NativeProjectProcedureTest.java | 6 +- proc/community/build.gradle | 3 + .../LabelPropagationMutateProcTest.java | 1 + .../ModularityOptimizationMutateProcTest.java | 1 + .../org/neo4j/gds/wcc/WccMutateProcTest.java | 1 + proc/machine-learning/build.gradle | 3 + ...sificationPredictPipelineExecutorTest.java | 1 + proc/test/build.gradle | 1 + .../java/org/neo4j/gds/ProcedureRunner.java | 5 +- procedures/extension/build.gradle | 1 + .../OpenGraphDataScienceExtension.java | 1 + procedures/facade/build.gradle | 3 + ...> GraphCatalogProcedureFacadeFactory.java} | 12 +-- .../GraphDataScienceProcedures.java | 38 ++++++--- .../GraphDataScienceProceduresBuilder.java | 24 ++++-- procedures/graph-catalog-facade/build.gradle | 47 +++++++++++ .../catalog/GraphCatalogProcedureFacade.java} | 10 +-- .../GraphDropGraphPropertiesResult.java | 0 .../gds/procedures/catalog/GraphInfo.java | 0 .../catalog/GraphInfoWithHistogram.java | 0 .../catalog/StreamGraphPropertyResult.java | 0 .../procedures/catalog/DummyGraphStore.java | 0 .../GraphCatalogProcedureFacadeTest.java} | 28 +++---- .../gds/procedures/catalog/GraphInfoTest.java | 0 .../catalog/GraphInfoWithHistogramTest.java | 0 procedures/integration/build.gradle | 1 + .../GraphDataScienceExtensionBuilder.java | 9 ++- .../integration/GraphDataScienceProvider.java | 25 +++--- .../GraphDataScienceProviderFactory.java | 25 +++--- procedures/model-catalog-facade/build.gradle | 11 +++ .../ModelCatalogProcedureFacade.java | 43 ++++++++++ .../ModelNameValidationService.java | 34 ++++++++ settings.gradle | 9 +++ 73 files changed, 601 insertions(+), 220 deletions(-) rename applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/{DefaultCatalogBusinessFacade.java => DefaultGraphCatalogApplications.java} (99%) rename applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/{DefaultCatalogBusinessFacadeBuilder.java => DefaultGraphCatalogApplicationsBuilder.java} (65%) rename applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/{CatalogBusinessFacade.java => GraphCatalogApplications.java} (99%) rename applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/{DefaultCatalogBusinessFacadeTest.java => DefaultGraphCatalogApplicationsTest.java} (95%) create mode 100644 applications/model-catalog/build.gradle create mode 100644 applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java create mode 100644 applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java rename {proc/catalog/src/main/java/org/neo4j/gds/model/catalog => applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog}/ModelExistsResult.java (94%) create mode 100644 applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelName.java rename procedures/facade/src/main/java/org/neo4j/gds/procedures/{CatalogProcedureFacadeFactory.java => GraphCatalogProcedureFacadeFactory.java} (91%) create mode 100644 procedures/graph-catalog-facade/build.gradle rename procedures/{facade/src/main/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacade.java => graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java} (98%) rename procedures/{facade => graph-catalog-facade}/src/main/java/org/neo4j/gds/procedures/catalog/GraphDropGraphPropertiesResult.java (100%) rename procedures/{facade => graph-catalog-facade}/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfo.java (100%) rename procedures/{facade => graph-catalog-facade}/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogram.java (100%) rename procedures/{facade => graph-catalog-facade}/src/main/java/org/neo4j/gds/procedures/catalog/StreamGraphPropertyResult.java (100%) rename procedures/{facade => graph-catalog-facade}/src/test/java/org/neo4j/gds/procedures/catalog/DummyGraphStore.java (100%) rename procedures/{facade/src/test/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacadeTest.java => graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java} (95%) rename procedures/{facade => graph-catalog-facade}/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoTest.java (100%) rename procedures/{facade => graph-catalog-facade}/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogramTest.java (100%) create mode 100644 procedures/model-catalog-facade/build.gradle create mode 100644 procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java create mode 100644 procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java diff --git a/alpha/alpha-proc/build.gradle b/alpha/alpha-proc/build.gradle index 53a1ea2c5a..8e2db80bfc 100644 --- a/alpha/alpha-proc/build.gradle +++ b/alpha/alpha-proc/build.gradle @@ -31,6 +31,7 @@ dependencies { implementation project(':core-utils') implementation project(':core-write') implementation project(':executor') + implementation project(':graph-catalog-procedure-facade') implementation project(':legacy-cypher-projection') implementation project(':memory-usage') implementation project(':neo4j-api') diff --git a/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java b/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java index d00da6cf61..9f3a167378 100644 --- a/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java +++ b/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java @@ -51,7 +51,7 @@ public UserLogProc() {} @Procedure("gds.userLog") @Description("Log warnings and hints for currently running tasks.") public Stream queryUserLog(@Name(value = "jobId", defaultValue = "") String jobId) { - return facade.catalog().queryUserLog(jobId); + return facade.graphCatalog().queryUserLog(jobId); } @Procedure(value = "gds.alpha.userLog", deprecatedBy = "gds.userLog") diff --git a/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java b/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java index 05963a116f..4a301fd58b 100644 --- a/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java +++ b/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java @@ -24,7 +24,7 @@ import org.neo4j.gds.core.utils.progress.tasks.LeafTask; import org.neo4j.gds.core.utils.warnings.UserLogEntry; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; import java.util.stream.Stream; @@ -43,8 +43,8 @@ void shouldLogUserWarnings() { new UserLogEntry(new LeafTask("lt", 87), "going twice..."), new UserLogEntry(new LeafTask("lt", 23), "gone!") ); - var catalogFacade = mock(CatalogProcedureFacade.class); - when(facade.catalog()).thenReturn(catalogFacade); + var catalogFacade = mock(GraphCatalogProcedureFacade.class); + when(facade.graphCatalog()).thenReturn(catalogFacade); when(catalogFacade.queryUserLog("unused")).thenReturn(expectedWarnings); var actualWarnings = userLogProc.queryUserLog("unused"); diff --git a/applications/facade/build.gradle b/applications/facade/build.gradle index 21600105b7..c2af37e7bf 100644 --- a/applications/facade/build.gradle +++ b/applications/facade/build.gradle @@ -16,6 +16,7 @@ dependencies { implementation project(":memory-estimation") implementation project(":metrics-api") implementation project(":model-catalog-api") + implementation project(":model-catalog-applications") implementation project(":miscellaneous-algorithms") implementation project(":node-embedding-algorithms") implementation project(":path-finding-algorithms") diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java index dddfb0ad38..e71cf15fcd 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java @@ -36,8 +36,10 @@ import org.neo4j.gds.applications.algorithms.miscellaneous.MiscellaneousApplications; import org.neo4j.gds.applications.algorithms.pathfinding.PathFindingApplications; import org.neo4j.gds.applications.algorithms.similarity.SimilarityApplications; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; -import org.neo4j.gds.applications.graphstorecatalog.DefaultCatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.DefaultGraphCatalogApplications; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.DefaultModelCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.core.loading.GraphStoreCatalogService; import org.neo4j.gds.core.model.ModelCatalog; import org.neo4j.gds.logging.Log; @@ -56,27 +58,30 @@ * and we apply a breakdown into sub-facades to keep things smaller and more manageable. */ public final class ApplicationsFacade { - private final CatalogBusinessFacade catalogBusinessFacade; private final CentralityApplications centralityApplications; private final CommunityApplications communityApplications; + private final GraphCatalogApplications graphCatalogApplications; private final MiscellaneousApplications miscellaneousApplications; + private final ModelCatalogApplications modelCatalogApplications; private final NodeEmbeddingApplications nodeEmbeddingApplications; private final PathFindingApplications pathFindingApplications; private final SimilarityApplications similarityApplications; ApplicationsFacade( - CatalogBusinessFacade catalogBusinessFacade, CentralityApplications centralityApplications, CommunityApplications communityApplications, + GraphCatalogApplications graphCatalogApplications, MiscellaneousApplications miscellaneousApplications, + ModelCatalogApplications modelCatalogApplications, NodeEmbeddingApplications nodeEmbeddingApplications, PathFindingApplications pathFindingApplications, SimilarityApplications similarityApplications ) { - this.catalogBusinessFacade = catalogBusinessFacade; this.centralityApplications = centralityApplications; this.communityApplications = communityApplications; + this.graphCatalogApplications = graphCatalogApplications; this.miscellaneousApplications = miscellaneousApplications; + this.modelCatalogApplications = modelCatalogApplications; this.nodeEmbeddingApplications = nodeEmbeddingApplications; this.pathFindingApplications = pathFindingApplications; this.similarityApplications = similarityApplications; @@ -88,7 +93,8 @@ public final class ApplicationsFacade { public static ApplicationsFacade create( Log log, Optional> algorithmProcessingTemplateDecorator, - Optional> catalogBusinessFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, GraphStoreCatalogService graphStoreCatalogService, MemoryGuard memoryGuard, AlgorithmMetricsService algorithmMetricsService, @@ -98,13 +104,6 @@ public static ApplicationsFacade create( ModelCatalog modelCatalog, GraphSageModelRepository graphSageModelRepository ) { - var catalogBusinessFacade = createCatalogBusinessFacade( - log, - catalogBusinessFacadeDecorator, - graphStoreCatalogService, - projectionMetricsService - ); - var databaseGraphStoreEstimationService = new DatabaseGraphStoreEstimationService( requestScopedDependencies.getGraphLoaderContext(), requestScopedDependencies.getUser() @@ -149,13 +148,29 @@ public static ApplicationsFacade create( mutateNodeProperty ); + var graphCatalogApplications = createGraphCatalogApplications( + log, + graphCatalogApplicationsDecorator, + graphStoreCatalogService, + projectionMetricsService + ); + var miscellaneousApplications = MiscellaneousApplications.create( - log, requestScopedDependencies, writeContext, algorithmEstimationTemplate, + log, + requestScopedDependencies, + writeContext, + algorithmEstimationTemplate, algorithmProcessingTemplateConvenience, progressTrackerCreator, mutateNodeProperty ); + var modelCatalogApplications = createModelCatalogApplications( + requestScopedDependencies, + modelCatalog, + modelCatalogApplicationsDecorator + ); + var nodeEmbeddingApplications = NodeEmbeddingApplications.create( log, requestScopedDependencies, @@ -189,10 +204,11 @@ public static ApplicationsFacade create( ); return new ApplicationsFacadeBuilder() - .with(catalogBusinessFacade) .with(centralityApplications) .with(communityApplications) + .with(graphCatalogApplications) .with(miscellaneousApplications) + .with(modelCatalogApplications) .with(nodeEmbeddingApplications) .with(pathFindingApplications) .with(similarityApplications) @@ -220,25 +236,36 @@ private static AlgorithmProcessingTemplate createAlgorithmProcessingTemplate( return algorithmProcessingTemplateDecorator.get().apply(algorithmProcessingTemplate); } - private static CatalogBusinessFacade createCatalogBusinessFacade( + private static GraphCatalogApplications createGraphCatalogApplications( Log log, - Optional> catalogBusinessFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, GraphStoreCatalogService graphStoreCatalogService, ProjectionMetricsService projectionMetricsService ) { - var catalogBusinessFacade = DefaultCatalogBusinessFacade.create( + var graphCatalogApplications = DefaultGraphCatalogApplications.create( log, graphStoreCatalogService, projectionMetricsService ); - if (catalogBusinessFacadeDecorator.isEmpty()) return catalogBusinessFacade; + if (graphCatalogApplicationsDecorator.isEmpty()) return graphCatalogApplications; - return catalogBusinessFacadeDecorator.get().apply(catalogBusinessFacade); + return graphCatalogApplicationsDecorator.get().apply(graphCatalogApplications); } - public CatalogBusinessFacade catalog() { - return catalogBusinessFacade; + private static ModelCatalogApplications createModelCatalogApplications( + RequestScopedDependencies requestScopedDependencies, + ModelCatalog modelCatalog, + Optional> modelCatalogApplicationsDecorator + ) { + var modelCatalogApplications = DefaultModelCatalogApplications.create( + modelCatalog, + requestScopedDependencies.getUser() + ); + + if (modelCatalogApplicationsDecorator.isEmpty()) return modelCatalogApplications; + + return modelCatalogApplicationsDecorator.get().apply(modelCatalogApplications); } public CentralityApplications centrality() { @@ -249,10 +276,18 @@ public CommunityApplications community() { return communityApplications; } + public GraphCatalogApplications graphCatalog() { + return graphCatalogApplications; + } + public MiscellaneousApplications miscellaneous() { return miscellaneousApplications; } + public ModelCatalogApplications modelCatalog() { + return modelCatalogApplications; + } + public NodeEmbeddingApplications nodeEmbeddings() { return nodeEmbeddingApplications; } diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java index 3d33d2b012..c6c92d0485 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java @@ -25,25 +25,22 @@ import org.neo4j.gds.applications.algorithms.miscellaneous.MiscellaneousApplications; import org.neo4j.gds.applications.algorithms.pathfinding.PathFindingApplications; import org.neo4j.gds.applications.algorithms.similarity.SimilarityApplications; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; /** * This is a helper that makes it easy to inject constituents, and to not have to inject all of them. */ public class ApplicationsFacadeBuilder { - private CatalogBusinessFacade catalogBusinessFacade; private CentralityApplications centralityApplications; private CommunityApplications communityApplications; + private GraphCatalogApplications graphCatalogApplications; private MiscellaneousApplications miscellaneousApplications; + private ModelCatalogApplications modelCatalogApplications; private NodeEmbeddingApplications nodeEmbeddingApplications; private PathFindingApplications pathFindingApplications; private SimilarityApplications similarityApplications; - public ApplicationsFacadeBuilder with(CatalogBusinessFacade catalogBusinessFacade) { - this.catalogBusinessFacade = catalogBusinessFacade; - return this; - } - public ApplicationsFacadeBuilder with(CentralityApplications centralityApplications) { this.centralityApplications = centralityApplications; return this; @@ -54,11 +51,21 @@ public ApplicationsFacadeBuilder with(CommunityApplications communityApplication return this; } + public ApplicationsFacadeBuilder with(GraphCatalogApplications graphCatalogApplications) { + this.graphCatalogApplications = graphCatalogApplications; + return this; + } + public ApplicationsFacadeBuilder with(MiscellaneousApplications miscellaneousApplications) { this.miscellaneousApplications = miscellaneousApplications; return this; } + public ApplicationsFacadeBuilder with(ModelCatalogApplications modelCatalogApplications) { + this.modelCatalogApplications = modelCatalogApplications; + return this; + } + public ApplicationsFacadeBuilder with(NodeEmbeddingApplications nodeEmbeddingApplications) { this.nodeEmbeddingApplications = nodeEmbeddingApplications; return this; @@ -76,10 +83,11 @@ public ApplicationsFacadeBuilder with(SimilarityApplications similarityApplicati public ApplicationsFacade build() { return new ApplicationsFacade( - catalogBusinessFacade, centralityApplications, communityApplications, + graphCatalogApplications, miscellaneousApplications, + modelCatalogApplications, nodeEmbeddingApplications, pathFindingApplications, similarityApplications diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java similarity index 99% rename from applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java rename to applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java index fb46195897..900c05da19 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java @@ -60,7 +60,7 @@ * Here we have just business logic: no Neo4j bits or other integration bits, just Java POJO things. *

* By nature business logic is going to be bespoke, so one method per logical thing. - * Take {@link DefaultCatalogBusinessFacade#graphExists(User, DatabaseId, String)} for example: + * Take {@link DefaultGraphCatalogApplications#graphExists(User, DatabaseId, String)} for example: * pure expressed business logic that layers above will use in multiple places, but! * Any marshalling happens in those layers, not here. *

@@ -72,7 +72,7 @@ * Ideally though this is a facade over many individual pieces of business logic in separate classes, * or behind other facades (oh gosh turtles, turtles everywhere :scream:). */ -public class DefaultCatalogBusinessFacade implements CatalogBusinessFacade { +public class DefaultGraphCatalogApplications implements GraphCatalogApplications { private final CatalogConfigurationService catalogConfigurationService = new CatalogConfigurationService(); private final GraphStoreValidationService graphStoreValidationService = new GraphStoreValidationService(); @@ -105,7 +105,7 @@ public class DefaultCatalogBusinessFacade implements CatalogBusinessFacade { private final EstimateCommonNeighbourAwareRandomWalkApplication estimateCommonNeighbourAwareRandomWalkApplication; private final GenerateGraphApplication generateGraphApplication; - DefaultCatalogBusinessFacade( + DefaultGraphCatalogApplications( Log log, GraphStoreCatalogService graphStoreCatalogService, ProjectionMetricsService projectionMetricsService, @@ -157,7 +157,7 @@ public class DefaultCatalogBusinessFacade implements CatalogBusinessFacade { this.generateGraphApplication = generateGraphApplication; } - public static CatalogBusinessFacade create( + public static GraphCatalogApplications create( Log log, GraphStoreCatalogService graphStoreCatalogService, ProjectionMetricsService projectionMetricsService @@ -199,7 +199,7 @@ public static CatalogBusinessFacade create( var writeRelationshipPropertiesApplication = new WriteRelationshipPropertiesApplication(log); var writeRelationshipsApplication = new WriteRelationshipsApplication(log); - var catalogFacade = new DefaultCatalogBusinessFacadeBuilder() + return new DefaultGraphCatalogApplicationsBuilder() .withLog(log) .withGraphStoreCatalogService(graphStoreCatalogService) .withProjectionMetricsService(projectionMetricsService) @@ -224,8 +224,6 @@ public static CatalogBusinessFacade create( .withWriteRelationshipPropertiesApplication(writeRelationshipPropertiesApplication) .withWriteRelationshipsApplication(writeRelationshipsApplication) .build(); - - return catalogFacade; } @Override diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeBuilder.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsBuilder.java similarity index 65% rename from applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeBuilder.java rename to applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsBuilder.java index c68e068e0a..db9bbe8d93 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeBuilder.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsBuilder.java @@ -25,8 +25,7 @@ - class DefaultCatalogBusinessFacadeBuilder { - + class DefaultGraphCatalogApplicationsBuilder { // global dependencies private Log log; private GraphStoreCatalogService graphStoreCatalogService; @@ -56,112 +55,112 @@ class DefaultCatalogBusinessFacadeBuilder { private EstimateCommonNeighbourAwareRandomWalkApplication estimateCommonNeighbourAwareRandomWalkApplication; private GenerateGraphApplication generateGraphApplication; - DefaultCatalogBusinessFacadeBuilder withLog(Log log) { + DefaultGraphCatalogApplicationsBuilder withLog(Log log) { this.log = log; return this; } - DefaultCatalogBusinessFacadeBuilder withGraphStoreCatalogService(GraphStoreCatalogService graphStoreCatalogService) { + DefaultGraphCatalogApplicationsBuilder withGraphStoreCatalogService(GraphStoreCatalogService graphStoreCatalogService) { this.graphStoreCatalogService = graphStoreCatalogService; return this; } - DefaultCatalogBusinessFacadeBuilder withProjectionMetricsService(ProjectionMetricsService projectionMetricsService) { + DefaultGraphCatalogApplicationsBuilder withProjectionMetricsService(ProjectionMetricsService projectionMetricsService) { this.projectionMetricsService = projectionMetricsService; return this; } - DefaultCatalogBusinessFacadeBuilder withGraphNameValidationService(GraphNameValidationService graphNameValidationService) { + DefaultGraphCatalogApplicationsBuilder withGraphNameValidationService(GraphNameValidationService graphNameValidationService) { this.graphNameValidationService = graphNameValidationService; return this; } - DefaultCatalogBusinessFacadeBuilder withCypherProjectApplication(CypherProjectApplication cypherProjectApplication) { + DefaultGraphCatalogApplicationsBuilder withCypherProjectApplication(CypherProjectApplication cypherProjectApplication) { this.cypherProjectApplication = cypherProjectApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withDropGraphApplication(DropGraphApplication dropGraphApplication) { + DefaultGraphCatalogApplicationsBuilder withDropGraphApplication(DropGraphApplication dropGraphApplication) { this.dropGraphApplication = dropGraphApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withDropNodePropertiesApplication(DropNodePropertiesApplication dropNodePropertiesApplication) { + DefaultGraphCatalogApplicationsBuilder withDropNodePropertiesApplication(DropNodePropertiesApplication dropNodePropertiesApplication) { this.dropNodePropertiesApplication=dropNodePropertiesApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withDropRelationshipsApplication(DropRelationshipsApplication dropRelationshipsApplication) { + DefaultGraphCatalogApplicationsBuilder withDropRelationshipsApplication(DropRelationshipsApplication dropRelationshipsApplication) { this.dropRelationshipsApplication = dropRelationshipsApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withEstimateCommonNeighbourAwareRandomWalkApplication(EstimateCommonNeighbourAwareRandomWalkApplication estimateCommonNeighbourAwareRandomWalkApplication) { + DefaultGraphCatalogApplicationsBuilder withEstimateCommonNeighbourAwareRandomWalkApplication(EstimateCommonNeighbourAwareRandomWalkApplication estimateCommonNeighbourAwareRandomWalkApplication) { this.estimateCommonNeighbourAwareRandomWalkApplication = estimateCommonNeighbourAwareRandomWalkApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withGenerateGraphApplication(GenerateGraphApplication generateGraphApplication) { + DefaultGraphCatalogApplicationsBuilder withGenerateGraphApplication(GenerateGraphApplication generateGraphApplication) { this.generateGraphApplication = generateGraphApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withGraphMemoryUsageApplication(GraphMemoryUsageApplication graphMemoryUsageApplication) { + DefaultGraphCatalogApplicationsBuilder withGraphMemoryUsageApplication(GraphMemoryUsageApplication graphMemoryUsageApplication) { this.graphMemoryUsageApplication= graphMemoryUsageApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withGraphSamplingApplication(GraphSamplingApplication graphSamplingApplication) { + DefaultGraphCatalogApplicationsBuilder withGraphSamplingApplication(GraphSamplingApplication graphSamplingApplication) { this.graphSamplingApplication = graphSamplingApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withListGraphApplication(ListGraphApplication listGraphApplication) { + DefaultGraphCatalogApplicationsBuilder withListGraphApplication(ListGraphApplication listGraphApplication) { this.listGraphApplication = listGraphApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withNativeProjectApplication(NativeProjectApplication nativeProjectApplication) { + DefaultGraphCatalogApplicationsBuilder withNativeProjectApplication(NativeProjectApplication nativeProjectApplication) { this.nativeProjectApplication = nativeProjectApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withNodeLabelMutatorApplication(NodeLabelMutatorApplication nodeLabelMutatorApplication) { + DefaultGraphCatalogApplicationsBuilder withNodeLabelMutatorApplication(NodeLabelMutatorApplication nodeLabelMutatorApplication) { this.nodeLabelMutatorApplication = nodeLabelMutatorApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withStreamNodePropertiesApplication(StreamNodePropertiesApplication streamNodePropertiesApplication) { + DefaultGraphCatalogApplicationsBuilder withStreamNodePropertiesApplication(StreamNodePropertiesApplication streamNodePropertiesApplication) { this.streamNodePropertiesApplication = streamNodePropertiesApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withStreamRelationshipPropertiesApplication(StreamRelationshipPropertiesApplication streamRelationshipPropertiesApplication) { + DefaultGraphCatalogApplicationsBuilder withStreamRelationshipPropertiesApplication(StreamRelationshipPropertiesApplication streamRelationshipPropertiesApplication) { this.streamRelationshipPropertiesApplication = streamRelationshipPropertiesApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withStreamRelationshipsApplication(StreamRelationshipsApplication streamRelationshipsApplication) { + DefaultGraphCatalogApplicationsBuilder withStreamRelationshipsApplication(StreamRelationshipsApplication streamRelationshipsApplication) { this.streamRelationshipsApplication= streamRelationshipsApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withSubGraphProjectApplication(SubGraphProjectApplication subGraphProjectApplication) { + DefaultGraphCatalogApplicationsBuilder withSubGraphProjectApplication(SubGraphProjectApplication subGraphProjectApplication) { this.subGraphProjectApplication = subGraphProjectApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withWriteNodeLabelApplication(WriteNodeLabelApplication writeNodeLabelApplication) { + DefaultGraphCatalogApplicationsBuilder withWriteNodeLabelApplication(WriteNodeLabelApplication writeNodeLabelApplication) { this.writeNodeLabelApplication = writeNodeLabelApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withWriteNodePropertiesApplication(WriteNodePropertiesApplication writeNodePropertiesApplication) { + DefaultGraphCatalogApplicationsBuilder withWriteNodePropertiesApplication(WriteNodePropertiesApplication writeNodePropertiesApplication) { this.writeNodePropertiesApplication = writeNodePropertiesApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withWriteRelationshipPropertiesApplication(WriteRelationshipPropertiesApplication writeRelationshipPropertiesApplication) { + DefaultGraphCatalogApplicationsBuilder withWriteRelationshipPropertiesApplication(WriteRelationshipPropertiesApplication writeRelationshipPropertiesApplication) { this.writeRelationshipPropertiesApplication = writeRelationshipPropertiesApplication; return this; } - DefaultCatalogBusinessFacadeBuilder withWriteRelationshipsApplication(WriteRelationshipsApplication writeRelationshipsApplication) { + DefaultGraphCatalogApplicationsBuilder withWriteRelationshipsApplication(WriteRelationshipsApplication writeRelationshipsApplication) { this.writeRelationshipsApplication = writeRelationshipsApplication; return this; } - DefaultCatalogBusinessFacade build(){ - return new DefaultCatalogBusinessFacade( + DefaultGraphCatalogApplications build(){ + return new DefaultGraphCatalogApplications( log, graphStoreCatalogService, projectionMetricsService, diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/CatalogBusinessFacade.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/GraphCatalogApplications.java similarity index 99% rename from applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/CatalogBusinessFacade.java rename to applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/GraphCatalogApplications.java index 6ac14042ce..68862039c7 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/CatalogBusinessFacade.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/GraphCatalogApplications.java @@ -43,7 +43,7 @@ import java.util.Map; import java.util.stream.Stream; -public interface CatalogBusinessFacade { +public interface GraphCatalogApplications { boolean graphExists(User user, DatabaseId databaseId, String graphNameAsString); List dropGraph( diff --git a/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java b/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsTest.java similarity index 95% rename from applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java rename to applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsTest.java index 14f816c4e4..c96ea2722f 100644 --- a/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java +++ b/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplicationsTest.java @@ -33,11 +33,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -class DefaultCatalogBusinessFacadeTest { +class DefaultGraphCatalogApplicationsTest { @Test void shouldDetermineGraphExists() { var service = mock(GraphStoreCatalogService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(service) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -55,7 +55,7 @@ void shouldDetermineGraphExists() { @Test void shouldDetermineGraphDoesNotExist() { var service = mock(GraphStoreCatalogService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(service) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -77,7 +77,7 @@ void shouldDetermineGraphDoesNotExist() { @Test void shouldValidateInputGraphName() { var service = mock(GraphStoreCatalogService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(service) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -90,7 +90,7 @@ void shouldValidateInputGraphName() { @Test void shouldUseStrictValidationWhenProjecting() { var validationService = mock(GraphNameValidationService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphNameValidationService(validationService) .build(); @@ -137,7 +137,7 @@ void shouldUseStrictValidationWhenProjecting() { */ @Test void shouldHandleNullsInNativeProjectParameters() { - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(mock(GraphStoreCatalogService.class)) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -210,7 +210,7 @@ void shouldHandleNullsInNativeProjectParameters() { */ @Test void shouldHandleNullsInCypherProjectParameters() { - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(mock(GraphStoreCatalogService.class)) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -281,7 +281,7 @@ void shouldHandleNullsInCypherProjectParameters() { @Test void shouldDoExistenceCheckWhenProjecting() { var graphStoreCatalogService = mock(GraphStoreCatalogService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(graphStoreCatalogService) .withGraphNameValidationService(new GraphNameValidationService()) .build(); @@ -340,7 +340,7 @@ void shouldDoExistenceCheckWhenProjecting() { @Test void shouldDoPositiveExistenceCheckWhenProjectingSubGraph() { var graphStoreCatalogService = mock(GraphStoreCatalogService.class); - var facade = new DefaultCatalogBusinessFacadeBuilder() + var facade = new DefaultGraphCatalogApplicationsBuilder() .withGraphStoreCatalogService(graphStoreCatalogService) .withGraphNameValidationService(new GraphNameValidationService()) .build(); diff --git a/applications/model-catalog/build.gradle b/applications/model-catalog/build.gradle new file mode 100644 index 0000000000..5a200d2d26 --- /dev/null +++ b/applications/model-catalog/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'java-library' + +description = 'Neo4j Graph Data Science :: Model Catalog Applications' + +group = 'org.neo4j.gds' + +dependencies { + implementation project(":config-api") + implementation project(":core") + implementation project(":model-catalog-api") + + implementation openGds.commons.lang3 +} diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java new file mode 100644 index 0000000000..bedc3bbe3e --- /dev/null +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java @@ -0,0 +1,51 @@ +/* + * 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.applications.modelcatalog; + +import org.neo4j.gds.api.User; +import org.neo4j.gds.core.model.Model; +import org.neo4j.gds.core.model.ModelCatalog; + +import java.util.Optional; + +public final class DefaultModelCatalogApplications implements ModelCatalogApplications { + private final ModelCatalog modelCatalog; + private final User user; + + private DefaultModelCatalogApplications(ModelCatalog modelCatalog, User user) { + this.modelCatalog = modelCatalog; + this.user = user; + } + + public static DefaultModelCatalogApplications create(ModelCatalog modelCatalog, User user) { + return new DefaultModelCatalogApplications(modelCatalog, user); + } + + @Override + public ModelExistsResult exists(ModelName modelName) { + var untypedModel = modelCatalog.getUntyped(user.getUsername(), modelName.getValue()); + + var modelType = Optional.ofNullable(untypedModel).map(Model::algoType).orElse("n/a"); + + var exists = modelCatalog.exists(user.getUsername(), modelName.getValue()); + + return new ModelExistsResult(modelName.getValue(), modelType, exists); + } +} diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java new file mode 100644 index 0000000000..720701115e --- /dev/null +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java @@ -0,0 +1,24 @@ +/* + * 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.applications.modelcatalog; + +public interface ModelCatalogApplications { + ModelExistsResult exists(ModelName modelName); +} diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsResult.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelExistsResult.java similarity index 94% rename from proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsResult.java rename to applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelExistsResult.java index cf10033ab7..57f2b9db9e 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsResult.java +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelExistsResult.java @@ -17,9 +17,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.gds.model.catalog; +package org.neo4j.gds.applications.modelcatalog; -@SuppressWarnings("unused") public class ModelExistsResult { public final String modelName; public final String modelType; diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelName.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelName.java new file mode 100644 index 0000000000..7354fa54cc --- /dev/null +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelName.java @@ -0,0 +1,60 @@ +/* + * 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.applications.modelcatalog; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +/** + * Micro types FTW! + */ +public final class ModelName { + private final String value; + + private ModelName(String value) { + this.value = value; + } + + /** + * Trim the incoming string and use that. + */ + public static ModelName parse(String modelNameAsString) { + return new ModelName(modelNameAsString.trim()); + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public String toString() { + return value; + } +} diff --git a/proc/catalog/build.gradle b/proc/catalog/build.gradle index 8943b62530..e786e75b98 100644 --- a/proc/catalog/build.gradle +++ b/proc/catalog/build.gradle @@ -24,16 +24,19 @@ dependencies { implementation project(':core-utils') implementation project(':core-write') implementation project(':cypher-aggregation') - implementation project(':legacy-cypher-projection') implementation project(':csv') implementation project(':executor') - implementation project(':graph-store-catalog-applications') + implementation project(':graph-catalog-procedure-facade') implementation project(':graph-sampling') implementation project(':graph-schema-api') + implementation project(':graph-store-catalog-applications') implementation project(':io-core') + implementation project(':legacy-cypher-projection') implementation project(':logging') implementation project(':memory-usage') implementation project(':model-catalog-api') + implementation project(':model-catalog-applications') + implementation project(':model-catalog-procedure-facade') implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':neo4j-settings') diff --git a/proc/catalog/src/main/java/org/neo4j/gds/beta/generator/GraphGenerateProc.java b/proc/catalog/src/main/java/org/neo4j/gds/beta/generator/GraphGenerateProc.java index 55d861ff17..77c8e8640e 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/beta/generator/GraphGenerateProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/beta/generator/GraphGenerateProc.java @@ -64,6 +64,6 @@ public Stream generate( @Name(value = "averageDegree") long averageDegree, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().generateGraph(graphName, nodeCount, averageDegree, configuration); + return facade.graphCatalog().generateGraph(graphName, nodeCount, averageDegree, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropGraphPropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropGraphPropertiesProc.java index f6385cfa92..8685740d7f 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropGraphPropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropGraphPropertiesProc.java @@ -60,6 +60,6 @@ public Stream run( @Name(value = "graphProperty") String graphProperty, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().dropGraphProperty(graphName, graphProperty, configuration); + return facade.graphCatalog().dropGraphProperty(graphName, graphProperty, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropNodePropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropNodePropertiesProc.java index 7ab711e451..5de4c5205b 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropNodePropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropNodePropertiesProc.java @@ -46,7 +46,7 @@ public Stream dropNodeProperties( @Name(value = "nodeProperties") @NotNull Object nodeProperties, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().dropNodeProperties(graphName, nodeProperties, configuration); + return facade.graphCatalog().dropNodeProperties(graphName, nodeProperties, configuration); } @SuppressWarnings("unused") @@ -66,7 +66,7 @@ public Stream removeNodeProperties( .warn( "Procedure `gds.graph.removeNodeProperties` has been deprecated, please use `gds.graph.nodeProperties.drop`."); - return facade.catalog().dropNodeProperties( + return facade.graphCatalog().dropNodeProperties( graphName, nodeProperties, configuration diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropProc.java index e07adc4a17..bc820e5873 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropProc.java @@ -50,6 +50,6 @@ public Stream dropGraph( @Name(value = "dbName", defaultValue = "") String dbName, @Name(value = "username", defaultValue = "") String username ) { - return facade.catalog().dropGraph(graphNameOrListOfGraphNames, failIfMissing, dbName, username); + return facade.graphCatalog().dropGraph(graphNameOrListOfGraphNames, failIfMissing, dbName, username); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropRelationshipProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropRelationshipProc.java index fd63c7caac..14f5cfe534 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropRelationshipProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphDropRelationshipProc.java @@ -43,7 +43,7 @@ public Stream dropRelationships( @Name(value = "graphName") String graphName, @Name(value = "relationshipType") String relationshipType ) { - return facade.catalog().dropRelationships(graphName, relationshipType); + return facade.graphCatalog().dropRelationships(graphName, relationshipType); } @SuppressWarnings("unused") @@ -61,6 +61,6 @@ public Stream deleteRelationships( .warn( "Procedure `gds.graph.deleteRelationships` has been deprecated, please use `gds.graph.relationships.drop`."); - return facade.catalog().dropRelationships(graphName, relationshipType); + return facade.graphCatalog().dropRelationships(graphName, relationshipType); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsFunc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsFunc.java index cdb0d9fd7e..1b9eff950f 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsFunc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsFunc.java @@ -38,6 +38,6 @@ public class GraphExistsFunc { @UserFunction("gds.graph.exists") @Description(EXISTS_DESCRIPTION) public boolean existsFunctionButBetter(@Name(value = "graphName") String graphName) { - return facade.catalog().graphExists(graphName, Function.identity()); + return facade.graphCatalog().graphExists(graphName, Function.identity()); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsProc.java index c522bea146..a89635b9c8 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphExistsProc.java @@ -42,6 +42,6 @@ public class GraphExistsProc { @Procedure(name = "gds.graph.exists", mode = READ) @Description(EXISTS_DESCRIPTION) public Stream existsBetter(@Name(value = "graphName") String graphName) { - return facade.catalog().graphExists(graphName, b -> Stream.of(new GraphExistsResult(graphName, b))); + return facade.graphCatalog().graphExists(graphName, b -> Stream.of(new GraphExistsResult(graphName, b))); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphFilterProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphFilterProc.java index 65cbe49c95..4d53579c5f 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphFilterProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphFilterProc.java @@ -47,7 +47,7 @@ public Stream filter( @Name(value = "relationshipFilter") String relationshipFilter, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().subGraphProject( + return facade.graphCatalog().subGraphProject( graphName, fromGraphName, nodeFilter, diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphListProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphListProc.java index adac26f8b0..3e569ff999 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphListProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphListProc.java @@ -28,7 +28,7 @@ import java.util.stream.Stream; -import static org.neo4j.gds.procedures.catalog.CatalogProcedureFacade.NO_VALUE_PLACEHOLDER; +import static org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade.NO_VALUE_PLACEHOLDER; import static org.neo4j.gds.catalog.GraphCatalogProcedureConstants.LIST_DESCRIPTION; import static org.neo4j.procedure.Mode.READ; @@ -49,6 +49,6 @@ public GraphListProc() { public Stream listGraphs( @Name(value = "graphName", defaultValue = NO_VALUE_PLACEHOLDER) String graphName ) { - return facade.catalog().listGraphs(graphName); + return facade.graphCatalog().listGraphs(graphName); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMemoryUsageProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMemoryUsageProc.java index e327236f2b..ab39a34aa8 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMemoryUsageProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMemoryUsageProc.java @@ -37,6 +37,6 @@ public class GraphMemoryUsageProc { @Internal @Procedure(name = "gds.internal.graph.sizeOf", mode = READ) public Stream list(@Name(value = "graphName") String graphName) { - return facade.catalog().sizeOf(graphName); + return facade.graphCatalog().sizeOf(graphName); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMutateNodeLabelProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMutateNodeLabelProc.java index 32b9e16ac3..11897c341a 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMutateNodeLabelProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphMutateNodeLabelProc.java @@ -44,7 +44,7 @@ public Stream mutate( @Name(value = "configuration") Map configuration ) { - return facade.catalog().mutateNodeLabel(graphName, nodeLabel, configuration); + return facade.graphCatalog().mutateNodeLabel(graphName, nodeLabel, configuration); } @Procedure(name = "gds.alpha.graph.nodeLabel.mutate", mode = READ, deprecatedBy = "gds.graph.nodeLabel.mutate") diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphProjectProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphProjectProc.java index 2b8f4c905b..9ef2c50cec 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphProjectProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphProjectProc.java @@ -57,7 +57,7 @@ public Stream project( @Name(value = "relationshipProjection") @Nullable Object relationshipProjection, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().nativeProject( + return facade.graphCatalog().nativeProject( graphName, nodeProjection, relationshipProjection, @@ -72,7 +72,7 @@ public Stream projectEstimate( @Name(value = "relationshipProjection") @Nullable Object relationshipProjection, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().estimateNativeProject(nodeProjection, relationshipProjection, configuration); + return facade.graphCatalog().estimateNativeProject(nodeProjection, relationshipProjection, configuration); } @Procedure(name = "gds.graph.project.cypher", mode = READ, deprecatedBy = "gds.graph.project Cypher projection as an aggregation function") @@ -88,7 +88,7 @@ public Stream projectCypher( .log() .warn("Procedure `gds.graph.project.cypher` has been deprecated, please look into cypher projection via `gds.graph.project`"); - return facade.catalog().cypherProject(graphName, nodeQuery, relationshipQuery, configuration); + return facade.graphCatalog().cypherProject(graphName, nodeQuery, relationshipQuery, configuration); } @Procedure(name = "gds.graph.project.cypher.estimate", mode = READ, deprecatedBy = "gds.graph.project Cypher projection as an aggregation function") @@ -103,7 +103,7 @@ public Stream projectCypherEstimate( .log() .warn("Procedure `gds.graph.project.cypher` has been deprecated, please look into cypher projection via `gds.graph.project`"); - return facade.catalog().estimateCypherProject(nodeQuery, relationshipQuery, configuration); + return facade.graphCatalog().estimateCypherProject(nodeQuery, relationshipQuery, configuration); } @Internal @@ -119,6 +119,6 @@ public Stream projectSubgraph( ) { facade.deprecatedProcedures().called("gds.beta.graph.project.subgraph"); facade.log().warn("Procedure `gds.beta.graph.project.subgraph` has been deprecated, please use `gds.graph.filter`."); - return facade.catalog().subGraphProject(graphName, fromGraphName, nodeFilter, relationshipFilter, configuration); + return facade.graphCatalog().subGraphProject(graphName, fromGraphName, nodeFilter, relationshipFilter, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphSampleProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphSampleProc.java index 020ae2d065..8e948e683f 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphSampleProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphSampleProc.java @@ -48,7 +48,7 @@ public Stream sampleRandomWalkWithRestarts( @Name(value = "fromGraphName") String fromGraphName, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().sampleRandomWalkWithRestarts(graphName, fromGraphName, configuration); + return facade.graphCatalog().sampleRandomWalkWithRestarts(graphName, fromGraphName, configuration); } @Internal @@ -75,7 +75,7 @@ public Stream sampleCNARW( @Name(value = "fromGraphName") String fromGraphName, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().sampleCommonNeighbourAwareRandomWalk(graphName, fromGraphName, configuration); + return facade.graphCatalog().sampleCommonNeighbourAwareRandomWalk(graphName, fromGraphName, configuration); } @SuppressWarnings("unused") @@ -85,6 +85,6 @@ public Stream estimateCNARW( @Name(value = "fromGraphName") String fromGraphName, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().estimateCommonNeighbourAwareRandomWalk(fromGraphName, configuration); + return facade.graphCatalog().estimateCommonNeighbourAwareRandomWalk(fromGraphName, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamGraphPropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamGraphPropertiesProc.java index ac1a1b1772..5d0926433a 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamGraphPropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamGraphPropertiesProc.java @@ -65,6 +65,6 @@ public Stream streamProperty( @Name(value = "graphProperty") String graphProperty, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamGraphProperty(graphName, graphProperty, configuration); + return facade.graphCatalog().streamGraphProperty(graphName, graphProperty, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamNodePropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamNodePropertiesProc.java index 77df5268c1..793dc51e03 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamNodePropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamNodePropertiesProc.java @@ -48,7 +48,7 @@ public Stream streamNodeProperties( @Name(value = "nodeLabels", defaultValue = "['*']") Object nodeLabels, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamNodeProperties( + return facade.graphCatalog().streamNodeProperties( graphName, nodeProperties, nodeLabels, @@ -74,7 +74,7 @@ public Stream deprecatedStreamNodeProperties( .warn( "Procedure `gds.graph.streamNodeProperties` has been deprecated, please use `gds.graph.nodeProperties.stream`."); - return facade.catalog().streamNodeProperties( + return facade.graphCatalog().streamNodeProperties( graphName, nodeProperties, nodeLabels, @@ -91,7 +91,7 @@ public Stream streamNodeProperty( @Name(value = "nodeLabels", defaultValue = "['*']") Object nodeLabels, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamNodeProperty( + return facade.graphCatalog().streamNodeProperty( graphName, nodeProperty, nodeLabels, @@ -116,7 +116,7 @@ public Stream streamProperty( .warn( "Procedure `gds.graph.streamNodeProperty` has been deprecated, please use `gds.graph.nodeProperty.stream`."); - return facade.catalog().streamNodeProperty( + return facade.graphCatalog().streamNodeProperty( graphName, nodeProperty, nodeLabels, diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipPropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipPropertiesProc.java index 3afe08078b..77840a2ef6 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipPropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipPropertiesProc.java @@ -49,7 +49,7 @@ public Stream streamRelationshipPropert @Name(value = "relationshipTypes", defaultValue = "['*']") Object relationshipTypes, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamRelationshipProperties( + return facade.graphCatalog().streamRelationshipProperties( graphName, relationshipProperties, relationshipTypes, configuration ); @@ -73,7 +73,7 @@ public Stream deprecatedStreamRelations .warn( "Procedure `gds.graph.streamRelationshipProperties` has been deprecated, please use `gds.graph.relationshipProperties.stream`."); - return facade.catalog().streamRelationshipProperties( + return facade.graphCatalog().streamRelationshipProperties( graphName, relationshipProperties, relationshipTypes, configuration ); @@ -88,7 +88,7 @@ public Stream streamRelationshipProperty( @Name(value = "relationshipTypes", defaultValue = "['*']") Object relationshipTypes, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamRelationshipProperty( + return facade.graphCatalog().streamRelationshipProperty( graphName, relationshipProperty, relationshipTypes, @@ -114,7 +114,7 @@ public Stream deprecatedStreamRelationshi .warn( "Procedure `gds.graph.streamRelationshipProperty` has been deprecated, please use `gds.graph.relationshipProperty.stream`."); - return facade.catalog().streamRelationshipProperty( + return facade.graphCatalog().streamRelationshipProperty( graphName, relationshipProperty, relationshipTypes, diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipsProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipsProc.java index 66b8c1d9d0..9f2b5db93b 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipsProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphStreamRelationshipsProc.java @@ -45,7 +45,7 @@ public Stream streamRelationships( @Name(value = "relationshipTypes", defaultValue = "['*']") Object relationshipTypes, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().streamRelationships(graphName, relationshipTypes, configuration); + return facade.graphCatalog().streamRelationships(graphName, relationshipTypes, configuration); } @Procedure(name = "gds.beta.graph.relationships.stream", mode = READ, deprecatedBy = "gds.graph.relationships.stream") @@ -61,6 +61,6 @@ public Stream betaStreamRelationships( facade.log().warn("Procedure `gds.beta.graph.relationships.stream` has been deprecated, please use `gds.graph.relationships.stream`."); - return facade.catalog().streamRelationships(graphName, relationshipTypes, configuration); + return facade.graphCatalog().streamRelationships(graphName, relationshipTypes, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodeLabelProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodeLabelProc.java index 77b32fac86..e7cf0c929e 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodeLabelProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodeLabelProc.java @@ -44,7 +44,7 @@ public Stream write( @Name(value = "nodeLabel") String nodeLabel, @Name(value = "configuration") Map configuration ) { - return facade.catalog().writeNodeLabel(graphName, nodeLabel, configuration); + return facade.graphCatalog().writeNodeLabel(graphName, nodeLabel, configuration); } @Procedure(name = "gds.alpha.graph.nodeLabel.write", mode = WRITE, deprecatedBy = "gds.graph.nodeLabel.write") @@ -63,6 +63,6 @@ public Stream alphaWrite( .warn( "Procedure `gds.alpha.graph.nodeLabel.write` has been deprecated, please use `gds.graph.nodeLabel.write`."); - return facade.catalog().writeNodeLabel(graphName, nodeLabel, configuration); + return facade.graphCatalog().writeNodeLabel(graphName, nodeLabel, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodePropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodePropertiesProc.java index 6ea8681b1f..690acaa5c0 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodePropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteNodePropertiesProc.java @@ -46,7 +46,7 @@ public Stream writeNodeProperties( @Name(value = "nodeLabels", defaultValue = "['*']") Object nodeLabels, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().writeNodeProperties(graphName, nodeProperties, nodeLabels, configuration); + return facade.graphCatalog().writeNodeProperties(graphName, nodeProperties, nodeLabels, configuration); } @Procedure(name = "gds.graph.writeNodeProperties", mode = WRITE, deprecatedBy = "gds.graph.nodeProperties.write") @@ -62,6 +62,6 @@ public Stream run( facade.deprecatedProcedures().called("gds.graph.writeNodeProperties"); facade.log().warn("Procedure `gds.graph.writeNodeProperties` has been deprecated, please use `gds.graph.nodeProperties.write`."); - return facade.catalog().writeNodeProperties(graphName, nodeProperties, nodeLabels, configuration); + return facade.graphCatalog().writeNodeProperties(graphName, nodeProperties, nodeLabels, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipProc.java index 2fc4bb0159..fddfbf5eb7 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipProc.java @@ -47,7 +47,7 @@ public Stream writeRelationships( @Name(value = "relationshipProperty", defaultValue = "") @Nullable String relationshipProperty, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.catalog().writeRelationships(graphName, relationshipType, relationshipProperty, configuration); + return facade.graphCatalog().writeRelationships(graphName, relationshipType, relationshipProperty, configuration); } @Procedure(name = "gds.graph.writeRelationship", mode = WRITE, deprecatedBy = "gds.graph.relationships.write") @@ -67,6 +67,6 @@ public Stream run( .warn( "Procedure `gds.graph.writeRelationship` has been deprecated, please use `gds.graph.relationships.write`."); - return facade.catalog().writeRelationships(graphName, relationshipType, relationshipProperty, configuration); + return facade.graphCatalog().writeRelationships(graphName, relationshipType, relationshipProperty, configuration); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipPropertiesProc.java b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipPropertiesProc.java index 2c6ca44541..430f1b9a9d 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipPropertiesProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/catalog/GraphWriteRelationshipPropertiesProc.java @@ -46,7 +46,7 @@ public Stream writeRelationshipProperties( @Name(value = "relationshipProperties") List relationshipProperties, @Name(value = "configuration") Map configuration ) { - return facade.catalog().writeRelationshipProperties( + return facade.graphCatalog().writeRelationshipProperties( graphName, relationshipType, relationshipProperties, diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsProc.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsProc.java index d9121edfc5..f88e0a4c21 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelExistsProc.java @@ -19,34 +19,28 @@ */ package org.neo4j.gds.model.catalog; -import org.neo4j.gds.core.model.Model; -import org.neo4j.gds.core.model.ModelCatalog; +import org.neo4j.gds.applications.modelcatalog.ModelExistsResult; +import org.neo4j.gds.procedures.GraphDataScienceProcedures; +import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Internal; import org.neo4j.procedure.Name; import org.neo4j.procedure.Procedure; -import java.util.Optional; import java.util.stream.Stream; import static org.neo4j.procedure.Mode.READ; -public class ModelExistsProc extends ModelCatalogProc { - +public class ModelExistsProc { private static final String DESCRIPTION = "Checks if a given model exists in the model catalog."; + @Context + public GraphDataScienceProcedures facade; + @Procedure(name = "gds.model.exists", mode = READ) @Description(DESCRIPTION) public Stream exists(@Name(value = "modelName") String modelName) { - validateModelName(modelName); - - ModelCatalog modelCatalog = executionContext().modelCatalog(); - - return Stream.of(new ModelExistsResult( - modelName, - Optional.ofNullable(modelCatalog.getUntyped(username(), modelName)).map(Model::algoType).orElse("n/a"), - modelCatalog.exists(username(), modelName) - )); + return facade.modelCatalog().exists(modelName); } @Procedure(name = "gds.beta.model.exists", mode = READ, deprecatedBy = "gds.model.exists") @@ -54,15 +48,11 @@ public Stream exists(@Name(value = "modelName") String modelN @Deprecated(forRemoval = true) @Internal public Stream betaExists(@Name(value = "modelName") String modelName) { - executionContext() - .metricsFacade() - .deprecatedProcedures().called("gds.beta.model.exists"); - - executionContext() + facade.deprecatedProcedures().called("gds.beta.model.exists"); + facade .log() .warn("Procedure `gds.beta.model.exists` has been deprecated, please use `gds.model.exists`."); return exists(modelName); } - } diff --git a/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphDropProcTest.java b/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphDropProcTest.java index 8a50c92298..6af7298deb 100644 --- a/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphDropProcTest.java +++ b/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphDropProcTest.java @@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; import org.neo4j.gds.procedures.catalog.GraphInfo; import java.util.stream.Stream; @@ -37,8 +37,8 @@ void shouldDelegateToFacade() { var procedure = new GraphDropProc(facade); var expectedResult = Stream.of(); - var catalogFacade = mock(CatalogProcedureFacade.class); - when(facade.catalog()).thenReturn(catalogFacade); + var catalogFacade = mock(GraphCatalogProcedureFacade.class); + when(facade.graphCatalog()).thenReturn(catalogFacade); when(catalogFacade.dropGraph("my graph", true, "some database", "some user")).thenReturn(expectedResult); var actualResult = procedure.dropGraph("my graph", true, "some database", "some user"); diff --git a/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphListProcTest.java b/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphListProcTest.java index 2d15dc0f89..b739940888 100644 --- a/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphListProcTest.java +++ b/proc/catalog/src/test/java/org/neo4j/gds/catalog/GraphListProcTest.java @@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; import org.neo4j.gds.procedures.catalog.GraphInfoWithHistogram; import java.util.stream.Stream; @@ -37,8 +37,8 @@ void shouldDelegateToFacade() { var procedure = new GraphListProc(facade); var expectedResultStream = Stream.of(mock(GraphInfoWithHistogram.class)); - var catalogFacade = mock(CatalogProcedureFacade.class); - when(facade.catalog()).thenReturn(catalogFacade); + var catalogFacade = mock(GraphCatalogProcedureFacade.class); + when(facade.graphCatalog()).thenReturn(catalogFacade); when(catalogFacade.listGraphs("some graph")).thenReturn(expectedResultStream); var actualResultStream = procedure.listGraphs("some graph"); diff --git a/proc/catalog/src/test/java/org/neo4j/gds/catalog/NativeProjectProcedureTest.java b/proc/catalog/src/test/java/org/neo4j/gds/catalog/NativeProjectProcedureTest.java index 57ab19b689..cf4313f54f 100644 --- a/proc/catalog/src/test/java/org/neo4j/gds/catalog/NativeProjectProcedureTest.java +++ b/proc/catalog/src/test/java/org/neo4j/gds/catalog/NativeProjectProcedureTest.java @@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; import org.neo4j.gds.projection.GraphProjectNativeResult; import java.util.Map; @@ -62,8 +62,8 @@ void shouldDelegateToFacade() { 87, 117 )); - var catalogFacade = mock(CatalogProcedureFacade.class); - when(facade.catalog()).thenReturn(catalogFacade); + var catalogFacade = mock(GraphCatalogProcedureFacade.class); + when(facade.graphCatalog()).thenReturn(catalogFacade); when(catalogFacade.nativeProject( "some graph", "some label", diff --git a/proc/community/build.gradle b/proc/community/build.gradle index a299bc180c..67057c3b9a 100644 --- a/proc/community/build.gradle +++ b/proc/community/build.gradle @@ -24,10 +24,13 @@ dependencies { implementation project(':core-write') implementation project(':defaults-and-limits-configuration') implementation project(':executor') + implementation project(':graph-catalog-procedure-facade') implementation project(':graph-schema-api') implementation project(':graph-store-catalog-applications') implementation project(':logging') implementation project(':memory-estimation') + implementation project(':model-catalog-applications') + implementation project(':model-catalog-procedure-facade') implementation project(':neo4j-api') implementation project(':node-embedding-algorithms') implementation project(':opengds-procedure-facade') diff --git a/proc/community/src/test/java/org/neo4j/gds/labelpropagation/LabelPropagationMutateProcTest.java b/proc/community/src/test/java/org/neo4j/gds/labelpropagation/LabelPropagationMutateProcTest.java index ff7292f0e6..8d8e66b85a 100644 --- a/proc/community/src/test/java/org/neo4j/gds/labelpropagation/LabelPropagationMutateProcTest.java +++ b/proc/community/src/test/java/org/neo4j/gds/labelpropagation/LabelPropagationMutateProcTest.java @@ -518,6 +518,7 @@ private GraphDataScienceProcedures constructFacade() { logMock, Optional.empty(), Optional.empty(), + Optional.empty(), graphStoreCatalogService, MemoryGuard.DISABLED, new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()), diff --git a/proc/community/src/test/java/org/neo4j/gds/modularityoptimization/ModularityOptimizationMutateProcTest.java b/proc/community/src/test/java/org/neo4j/gds/modularityoptimization/ModularityOptimizationMutateProcTest.java index df375d03db..85e33d4ad8 100644 --- a/proc/community/src/test/java/org/neo4j/gds/modularityoptimization/ModularityOptimizationMutateProcTest.java +++ b/proc/community/src/test/java/org/neo4j/gds/modularityoptimization/ModularityOptimizationMutateProcTest.java @@ -523,6 +523,7 @@ private GraphDataScienceProcedures createFacade() { logMock, Optional.empty(), Optional.empty(), + Optional.empty(), graphStoreCatalogService, MemoryGuard.DISABLED, new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()), diff --git a/proc/community/src/test/java/org/neo4j/gds/wcc/WccMutateProcTest.java b/proc/community/src/test/java/org/neo4j/gds/wcc/WccMutateProcTest.java index c00551da1a..babecaf5fc 100644 --- a/proc/community/src/test/java/org/neo4j/gds/wcc/WccMutateProcTest.java +++ b/proc/community/src/test/java/org/neo4j/gds/wcc/WccMutateProcTest.java @@ -588,6 +588,7 @@ private GraphDataScienceProcedures constructGraphDataScienceProcedures() { logMock, Optional.empty(), Optional.empty(), + Optional.empty(), graphStoreCatalogService, MemoryGuard.DISABLED, new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()), diff --git a/proc/machine-learning/build.gradle b/proc/machine-learning/build.gradle index b17aa155ca..82de27347c 100644 --- a/proc/machine-learning/build.gradle +++ b/proc/machine-learning/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation project(':core-write') implementation project(':defaults-and-limits-configuration') implementation project(':executor') + implementation project(':graph-catalog-procedure-facade') implementation project(':graph-schema-api') implementation project(':graph-store-catalog-applications') implementation project(':memory-usage') @@ -42,6 +43,8 @@ dependencies { implementation project(':ml-api') implementation project(':ml-core') implementation project(':model-catalog-api') + implementation project(':model-catalog-applications') + implementation project(':model-catalog-procedure-facade') implementation project(':neo4j-api') implementation project(':node-embedding-algorithms') implementation project(':opengds-procedure-facade') diff --git a/proc/machine-learning/src/test/java/org/neo4j/gds/ml/pipeline/node/classification/predict/NodeClassificationPredictPipelineExecutorTest.java b/proc/machine-learning/src/test/java/org/neo4j/gds/ml/pipeline/node/classification/predict/NodeClassificationPredictPipelineExecutorTest.java index d26b993c27..222ecf27e9 100644 --- a/proc/machine-learning/src/test/java/org/neo4j/gds/ml/pipeline/node/classification/predict/NodeClassificationPredictPipelineExecutorTest.java +++ b/proc/machine-learning/src/test/java/org/neo4j/gds/ml/pipeline/node/classification/predict/NodeClassificationPredictPipelineExecutorTest.java @@ -433,6 +433,7 @@ private static AlgorithmsProcedureFacade createAlgorithmsProcedureFacade() { null, Optional.empty(), Optional.empty(), + Optional.empty(), null, null, null, diff --git a/proc/test/build.gradle b/proc/test/build.gradle index 88174c03e6..2325245e75 100644 --- a/proc/test/build.gradle +++ b/proc/test/build.gradle @@ -31,6 +31,7 @@ dependencies { implementation project(':logging') implementation project(':memory-estimation') implementation project(':memory-usage') + implementation project(':model-catalog-applications') implementation project(':neo4j-api') implementation project(':neo4j-log-adapter') implementation project(':node-embedding-algorithms') diff --git a/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java b/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java index 0734c3dab5..31d0f4e03a 100644 --- a/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java +++ b/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java @@ -40,7 +40,7 @@ import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.metrics.procedures.DeprecatedProceduresMetricService; import org.neo4j.gds.procedures.AlgorithmProcedureFacadeBuilderFactory; -import org.neo4j.gds.procedures.CatalogProcedureFacadeFactory; +import org.neo4j.gds.procedures.GraphCatalogProcedureFacadeFactory; import org.neo4j.gds.procedures.DatabaseIdAccessor; import org.neo4j.gds.procedures.GraphDataScienceProcedures; import org.neo4j.gds.procedures.ProcedureCallContextReturnColumns; @@ -166,7 +166,7 @@ private static GraphDataScienceProcedures createGraphDataScienceProcedures( .build(); var graphStoreCatalogService = new GraphStoreCatalogService(); - var catalogProcedureFacadeFactory = new CatalogProcedureFacadeFactory(gdsLog); + var catalogProcedureFacadeFactory = new GraphCatalogProcedureFacadeFactory(gdsLog); var modelCatalog = new OpenModelCatalog(); @@ -182,6 +182,7 @@ private static GraphDataScienceProcedures createGraphDataScienceProcedures( LimitsConfiguration.Instance, Optional.empty(), Optional.empty(), + Optional.empty(), graphStoreCatalogService, MemoryGuard.DISABLED, MetricsFacade.PASSTHROUGH_METRICS_FACADE.algorithmMetrics(), diff --git a/procedures/extension/build.gradle b/procedures/extension/build.gradle index 345da68f8e..a9ac1cc50f 100644 --- a/procedures/extension/build.gradle +++ b/procedures/extension/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation project(':logging') implementation project(':metrics-api') implementation project(':ml-algo') + implementation project(':model-catalog-applications') implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':neo4j-kernel-adapter') diff --git a/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java b/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java index ce5bf86728..a4d3154c40 100644 --- a/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java +++ b/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java @@ -66,6 +66,7 @@ public Lifecycle newInstance(ExtensionContext extensionContext, Dependencies dep dependencies.globalProcedures(), Optional.empty(), // no extra checks in OpenGDS Optional.empty(), // no extra checks in OpenGDS + Optional.empty(), // no extra checks in OpenGDS exporterBuildersProviderService, metricsFacade, modelCatalog, diff --git a/procedures/facade/build.gradle b/procedures/facade/build.gradle index 369ed085a1..69dd662097 100644 --- a/procedures/facade/build.gradle +++ b/procedures/facade/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation project(':core-write') implementation project(':defaults-and-limits-configuration') implementation project(':executor') + implementation project(':graph-catalog-procedure-facade') implementation project(':graph-schema-api') implementation project(':graph-store-catalog-applications') implementation project(':legacy-cypher-projection') @@ -39,6 +40,8 @@ dependencies { implementation project(':ml-api') implementation project(':ml-core') implementation project(':model-catalog-api') + implementation project(':model-catalog-applications') + implementation project(':model-catalog-procedure-facade') implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':node-embedding-algorithms') diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/CatalogProcedureFacadeFactory.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphCatalogProcedureFacadeFactory.java similarity index 91% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/CatalogProcedureFacadeFactory.java rename to procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphCatalogProcedureFacadeFactory.java index 8efe7c90a9..a165aa6e26 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/CatalogProcedureFacadeFactory.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphCatalogProcedureFacadeFactory.java @@ -26,7 +26,7 @@ import org.neo4j.gds.applications.graphstorecatalog.GraphProjectMemoryUsageService; import org.neo4j.gds.compat.Neo4jProxy; import org.neo4j.gds.logging.Log; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; import org.neo4j.kernel.api.KernelTransaction; @@ -34,12 +34,12 @@ import java.util.function.Consumer; /** - * Here we keep everything related to constructing the {@link org.neo4j.gds.procedures.catalog.CatalogProcedureFacade} + * Here we keep everything related to constructing the {@link org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade} * from a {@link org.neo4j.kernel.api.procedure.Context}, at request time. *

* We can resolve things like user and database id here, construct termination flags, and such. */ -public class CatalogProcedureFacadeFactory { +public class GraphCatalogProcedureFacadeFactory { // dull bits private final TransactionContextAccessor transactionContextAccessor = new TransactionContextAccessor(); @@ -52,7 +52,7 @@ public class CatalogProcedureFacadeFactory { * Without it, I would have to stub out Neo4j's {@link org.neo4j.kernel.api.procedure.Context}, in a non-trivial, * ugly way. Now instead I can inject the user by stubbing out GDS' own little POJO service. */ - public CatalogProcedureFacadeFactory(Log log) { + public GraphCatalogProcedureFacadeFactory(Log log) { this.log = log; } @@ -60,7 +60,7 @@ public CatalogProcedureFacadeFactory(Log log) { * We construct the catalog facade at request time. At this point things like user and database id are set in stone. * And we can readily construct things like termination flags. */ - CatalogProcedureFacade createCatalogProcedureFacade( + GraphCatalogProcedureFacade createGraphCatalogProcedureFacade( ApplicationsFacade applicationsFacade, GraphDatabaseService graphDatabaseService, KernelTransaction kernelTransaction, @@ -82,7 +82,7 @@ public void accept(AutoCloseable autoCloseable) { procedureTransaction ); - return new CatalogProcedureFacade( + return new GraphCatalogProcedureFacade( requestScopedDependencies, streamCloser, graphDatabaseService, diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java index 70255a901e..7f1852cc8e 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java @@ -27,7 +27,8 @@ import org.neo4j.gds.applications.algorithms.machinery.MemoryGuard; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.applications.algorithms.machinery.WriteContext; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.configuration.DefaultsConfiguration; import org.neo4j.gds.configuration.LimitsConfiguration; import org.neo4j.gds.core.loading.GraphStoreCatalogService; @@ -39,7 +40,8 @@ import org.neo4j.gds.procedures.algorithms.AlgorithmsProcedureFacade; import org.neo4j.gds.procedures.algorithms.configuration.ConfigurationCreator; import org.neo4j.gds.procedures.algorithms.configuration.ConfigurationParser; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; +import org.neo4j.gds.procedures.modelcatalog.ModelCatalogProcedureFacade; import org.neo4j.gds.procedures.operations.OperationsProcedureFacade; import org.neo4j.gds.procedures.pipelines.PipelinesProcedureFacade; import org.neo4j.graphdb.GraphDatabaseService; @@ -53,7 +55,8 @@ public class GraphDataScienceProcedures { private final Log log; private final AlgorithmsProcedureFacade algorithmsProcedureFacade; - private final CatalogProcedureFacade catalogProcedureFacade; + private final GraphCatalogProcedureFacade graphCatalogProcedureFacade; + private final ModelCatalogProcedureFacade modelCatalogProcedureFacade; private final OperationsProcedureFacade operationsProcedureFacade; private final PipelinesProcedureFacade pipelinesProcedureFacade; @@ -65,14 +68,16 @@ public class GraphDataScienceProcedures { GraphDataScienceProcedures( Log log, AlgorithmsProcedureFacade algorithmsProcedureFacade, - CatalogProcedureFacade catalogProcedureFacade, + GraphCatalogProcedureFacade graphCatalogProcedureFacade, + ModelCatalogProcedureFacade modelCatalogProcedureFacade, OperationsProcedureFacade operationsProcedureFacade, PipelinesProcedureFacade pipelinesProcedureFacade, DeprecatedProceduresMetricService deprecatedProceduresMetricService ) { this.log = log; this.algorithmsProcedureFacade = algorithmsProcedureFacade; - this.catalogProcedureFacade = catalogProcedureFacade; + this.graphCatalogProcedureFacade = graphCatalogProcedureFacade; + this.modelCatalogProcedureFacade = modelCatalogProcedureFacade; this.operationsProcedureFacade = operationsProcedureFacade; this.pipelinesProcedureFacade = pipelinesProcedureFacade; this.deprecatedProceduresMetricService = deprecatedProceduresMetricService; @@ -83,7 +88,8 @@ public static GraphDataScienceProcedures create( DefaultsConfiguration defaultsConfiguration, LimitsConfiguration limitsConfiguration, Optional> algorithmProcessingTemplateDecorator, - Optional> catalogBusinessFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, GraphStoreCatalogService graphStoreCatalogService, MemoryGuard memoryGuard, AlgorithmMetricsService algorithmMetricsService, @@ -93,7 +99,7 @@ public static GraphDataScienceProcedures create( RequestScopedDependencies requestScopedDependencies, WriteContext writeContext, ProcedureReturnColumns procedureReturnColumns, - CatalogProcedureFacadeFactory catalogProcedureFacadeFactory, + GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory, GraphDatabaseService graphDatabaseService, Transaction transaction, AlgorithmProcedureFacadeBuilderFactory algorithmProcedureFacadeBuilderFactory, @@ -104,7 +110,8 @@ public static GraphDataScienceProcedures create( var applicationsFacade = ApplicationsFacade.create( log, algorithmProcessingTemplateDecorator, - catalogBusinessFacadeDecorator, + graphCatalogApplicationsDecorator, + modelCatalogApplicationsDecorator, graphStoreCatalogService, memoryGuard, algorithmMetricsService, @@ -115,7 +122,7 @@ public static GraphDataScienceProcedures create( graphSageModelRepository ); - var catalogProcedureFacade = catalogProcedureFacadeFactory.createCatalogProcedureFacade( + var graphCatalogProcedureFacade = graphCatalogProcedureFacadeFactory.createGraphCatalogProcedureFacade( applicationsFacade, graphDatabaseService, kernelTransaction, @@ -125,6 +132,8 @@ public static GraphDataScienceProcedures create( procedureReturnColumns ); + var modelCatalogProcedureFacade = new ModelCatalogProcedureFacade(applicationsFacade); + var configurationParser = new ConfigurationParser(defaultsConfiguration, limitsConfiguration); var configurationCreator = new ConfigurationCreator(configurationParser, requestScopedDependencies.getUser()); @@ -150,10 +159,11 @@ public static GraphDataScienceProcedures create( var pipelinesProcedureFacade = new PipelinesProcedureFacade(requestScopedDependencies.getUser()); return new GraphDataScienceProceduresBuilder(log) - .with(catalogProcedureFacade) .with(centralityProcedureFacade) .with(communityProcedureFacade) + .with(graphCatalogProcedureFacade) .with(miscellaneousProcedureFacade) + .with(modelCatalogProcedureFacade) .with(nodeEmbeddingsProcedureFacade) .with(operationsProcedureFacade) .with(pathFindingProcedureFacade) @@ -171,8 +181,12 @@ public AlgorithmsProcedureFacade algorithms() { return algorithmsProcedureFacade; } - public CatalogProcedureFacade catalog() { - return catalogProcedureFacade; + public GraphCatalogProcedureFacade graphCatalog() { + return graphCatalogProcedureFacade; + } + + public ModelCatalogProcedureFacade modelCatalog() { + return modelCatalogProcedureFacade; } public OperationsProcedureFacade operations() { diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProceduresBuilder.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProceduresBuilder.java index 8464a1f85b..e3ebefec59 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProceduresBuilder.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProceduresBuilder.java @@ -28,7 +28,8 @@ import org.neo4j.gds.procedures.algorithms.miscellaneous.MiscellaneousProcedureFacade; import org.neo4j.gds.procedures.algorithms.pathfinding.PathFindingProcedureFacade; import org.neo4j.gds.procedures.algorithms.similarity.SimilarityProcedureFacade; -import org.neo4j.gds.procedures.catalog.CatalogProcedureFacade; +import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; +import org.neo4j.gds.procedures.modelcatalog.ModelCatalogProcedureFacade; import org.neo4j.gds.procedures.operations.OperationsProcedureFacade; import org.neo4j.gds.procedures.pipelines.PipelinesProcedureFacade; @@ -41,9 +42,10 @@ public class GraphDataScienceProceduresBuilder { private final Log log; private CentralityProcedureFacade centralityProcedureFacade; - private CatalogProcedureFacade catalogProcedureFacade; + private GraphCatalogProcedureFacade graphCatalogProcedureFacade; private CommunityProcedureFacade communityProcedureFacade; private MiscellaneousProcedureFacade miscellaneousProcedureFacade; + private ModelCatalogProcedureFacade modelCatalogProcedureFacade; private NodeEmbeddingsProcedureFacade nodeEmbeddingsProcedureFacade; private OperationsProcedureFacade operationsProcedureFacade; private PathFindingProcedureFacade pathFindingProcedureFacade; @@ -55,11 +57,6 @@ public GraphDataScienceProceduresBuilder(Log log) { this.log = log; } - public GraphDataScienceProceduresBuilder with(CatalogProcedureFacade catalogProcedureFacade) { - this.catalogProcedureFacade = catalogProcedureFacade; - return this; - } - public GraphDataScienceProceduresBuilder with(CentralityProcedureFacade centralityProcedureFacade) { this.centralityProcedureFacade = centralityProcedureFacade; return this; @@ -70,11 +67,21 @@ public GraphDataScienceProceduresBuilder with(CommunityProcedureFacade community return this; } + public GraphDataScienceProceduresBuilder with(GraphCatalogProcedureFacade graphCatalogProcedureFacade) { + this.graphCatalogProcedureFacade = graphCatalogProcedureFacade; + return this; + } + public GraphDataScienceProceduresBuilder with(MiscellaneousProcedureFacade miscellaneousProcedureFacade) { this.miscellaneousProcedureFacade = miscellaneousProcedureFacade; return this; } + public GraphDataScienceProceduresBuilder with(ModelCatalogProcedureFacade modelCatalogProcedureFacade) { + this.modelCatalogProcedureFacade = modelCatalogProcedureFacade; + return this; + } + public GraphDataScienceProceduresBuilder with(NodeEmbeddingsProcedureFacade nodeEmbeddingsProcedureFacade) { this.nodeEmbeddingsProcedureFacade = nodeEmbeddingsProcedureFacade; return this; @@ -118,7 +125,8 @@ public GraphDataScienceProcedures build() { return new GraphDataScienceProcedures( log, algorithmsProcedureFacade, - catalogProcedureFacade, + graphCatalogProcedureFacade, + modelCatalogProcedureFacade, operationsProcedureFacade, pipelinesProcedureFacade, deprecatedProceduresMetricService diff --git a/procedures/graph-catalog-facade/build.gradle b/procedures/graph-catalog-facade/build.gradle new file mode 100644 index 0000000000..74b71389ce --- /dev/null +++ b/procedures/graph-catalog-facade/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'java-library' + +description = 'Neo4j Graph Data Science :: Graph Catalog Procedure Facade' + +group = 'org.neo4j.gds' + +dependencies { + neodeps().each { + compileOnly(group: 'org.neo4j', name: it, version: ver.'neo4j') { + transitive = false + } + + testImplementation(group: 'org.neo4j', name: it, version: ver.'neo4j') + } + + implementation project(':algorithms-machinery') + implementation project(':annotations') + implementation project(':applications-facade') + implementation project(':centrality-algorithms') + implementation project(':community-algorithms') + implementation project(':config-api') + implementation project(':core') + implementation project(':core-write') + implementation project(':graph-schema-api') + implementation project(':graph-store-catalog-applications') + implementation project(':legacy-cypher-projection') + implementation project(':memory-usage') + implementation project(':miscellaneous-algorithms') + implementation project(':model-catalog-applications') + implementation project(':native-projection') + implementation project(':neo4j-api') + implementation project(':node-embedding-algorithms') + implementation project(':path-finding-algorithms') + implementation project(':progress-tracking') + implementation project(':similarity-algorithms') + implementation project(':subgraph-filtering') + implementation project(':termination') + implementation project(':transaction') + + testImplementation platform(openGds.junit5bom) + testImplementation openGds.junit5.jupiter.api + testImplementation openGds.junit5.jupiter.params + testImplementation openGds.mockito.junit.jupiter + testImplementation openGds.assertj.core + + testRuntimeOnly openGds.junit5.jupiter.engine +} diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacade.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java similarity index 98% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacade.java rename to procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java index a5454f437c..95d0881265 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacade.java +++ b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java @@ -24,7 +24,7 @@ import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.applications.algorithms.machinery.WriteContext; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.graphstorecatalog.GraphGenerationStats; import org.neo4j.gds.applications.graphstorecatalog.GraphMemoryUsage; import org.neo4j.gds.applications.graphstorecatalog.GraphProjectMemoryUsageService; @@ -65,7 +65,7 @@ *

* This class gets constructed per request. */ -public class CatalogProcedureFacade { +public class GraphCatalogProcedureFacade { /** * This exists because procedures need default values sometimes. * For example, CALL gds.graph.list() would fail otherwise, @@ -87,7 +87,7 @@ public class CatalogProcedureFacade { /** * @param streamCloser A special thing needed for property streaming */ - public CatalogProcedureFacade( + public GraphCatalogProcedureFacade( RequestScopedDependencies requestScopedDependencies, Consumer streamCloser, GraphDatabaseService graphDatabaseService, @@ -698,7 +698,7 @@ private String validateValue(String graphName) { return graphName; } - private CatalogBusinessFacade catalog() { - return applicationsFacade.catalog(); + private GraphCatalogApplications catalog() { + return applicationsFacade.graphCatalog(); } } diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphDropGraphPropertiesResult.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphDropGraphPropertiesResult.java similarity index 100% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphDropGraphPropertiesResult.java rename to procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphDropGraphPropertiesResult.java diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfo.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfo.java similarity index 100% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfo.java rename to procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfo.java diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogram.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogram.java similarity index 100% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogram.java rename to procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogram.java diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/StreamGraphPropertyResult.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/StreamGraphPropertyResult.java similarity index 100% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/catalog/StreamGraphPropertyResult.java rename to procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/StreamGraphPropertyResult.java diff --git a/procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/DummyGraphStore.java b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/DummyGraphStore.java similarity index 100% rename from procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/DummyGraphStore.java rename to procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/DummyGraphStore.java diff --git a/procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacadeTest.java b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java similarity index 95% rename from procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacadeTest.java rename to procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java index 33d3fce04f..165e7a0acb 100644 --- a/procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/CatalogProcedureFacadeTest.java +++ b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java @@ -47,7 +47,7 @@ import org.neo4j.gds.applications.ApplicationsFacadeBuilder; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.applications.algorithms.machinery.WriteContext; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.config.GraphProjectConfig; import org.neo4j.gds.core.loading.Capabilities; import org.neo4j.gds.core.loading.DeletionResult; @@ -70,11 +70,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class CatalogProcedureFacadeTest { +class GraphCatalogProcedureFacadeTest { @Test void shouldDetermineIfGraphExists() { - var businessFacade = mock(CatalogBusinessFacade.class); - var catalogFacade = new CatalogProcedureFacade( + var businessFacade = mock(GraphCatalogApplications.class); + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(DatabaseId.of("current database")) .with(new User("current user", false)) @@ -109,8 +109,8 @@ void shouldDetermineIfGraphExists() { @Test void shouldQueryUserLog() { var userLogStore = mock(UserLogStore.class); - var businessFacade = mock(CatalogBusinessFacade.class); - var catalogFacade = new CatalogProcedureFacade( + var businessFacade = mock(GraphCatalogApplications.class); + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(DatabaseId.of("current database")) .with(new User("current user", false)) @@ -139,10 +139,10 @@ void shouldQueryUserLog() { @Test void shouldListGraphsWithoutDegreeDistribution() { var procedureReturnColumns = mock(ProcedureReturnColumns.class); - var businessFacade = mock(CatalogBusinessFacade.class); + var businessFacade = mock(GraphCatalogApplications.class); var procedureContext = WriteContext.builder().build(); - var catalogFacade = new CatalogProcedureFacade( + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(new User("Bob", false)) .build(), @@ -175,10 +175,10 @@ void shouldListGraphsWithoutDegreeDistribution() { @Test void shouldListGraphsWithDegreeDistribution() { var procedureReturnColumns = mock(ProcedureReturnColumns.class); - var businessFacade = mock(CatalogBusinessFacade.class); + var businessFacade = mock(GraphCatalogApplications.class); var procedureContext = WriteContext.builder().build(); - var catalogFacade = new CatalogProcedureFacade( + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(new User("Bob", false)) .build(), @@ -223,10 +223,10 @@ void shouldListGraphsWithDegreeDistribution() { @Test void shouldListGraphsWithoutMemoryUsage() { var procedureReturnColumns = mock(ProcedureReturnColumns.class); - var businessFacade = mock(CatalogBusinessFacade.class); + var businessFacade = mock(GraphCatalogApplications.class); var procedureContext = WriteContext.builder().build(); - var catalogFacade = new CatalogProcedureFacade( + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(new User("Bob", false)) .build(), @@ -262,10 +262,10 @@ void shouldListGraphsWithoutMemoryUsage() { @ValueSource(strings = {"memoryUsage", "sizeInBytes"}) void shouldListGraphsWithMemoryUsage(String returnColumn) { var procedureReturnColumns = mock(ProcedureReturnColumns.class); - var businessFacade = mock(CatalogBusinessFacade.class); + var businessFacade = mock(GraphCatalogApplications.class); var procedureContext = WriteContext.builder().build(); - var catalogFacade = new CatalogProcedureFacade( + var catalogFacade = new GraphCatalogProcedureFacade( RequestScopedDependencies.builder() .with(new User("Bob", false)) .build(), diff --git a/procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoTest.java b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoTest.java similarity index 100% rename from procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoTest.java rename to procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoTest.java diff --git a/procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogramTest.java b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogramTest.java similarity index 100% rename from procedures/facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogramTest.java rename to procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphInfoWithHistogramTest.java diff --git a/procedures/integration/build.gradle b/procedures/integration/build.gradle index b836785e13..26cc5d094a 100644 --- a/procedures/integration/build.gradle +++ b/procedures/integration/build.gradle @@ -30,6 +30,7 @@ dependencies { implementation project(':memory-usage') implementation project(':metrics-api') implementation project(':model-catalog-api') + implementation project(':model-catalog-applications') implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':neo4j-log-adapter') diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceExtensionBuilder.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceExtensionBuilder.java index 18adce4688..a043b17eac 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceExtensionBuilder.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceExtensionBuilder.java @@ -22,7 +22,8 @@ import org.apache.commons.lang3.tuple.Pair; import org.neo4j.gds.applications.algorithms.embeddings.GraphSageModelRepository; import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.core.model.ModelCatalog; import org.neo4j.gds.core.utils.mem.GcListenerExtension; import org.neo4j.gds.core.utils.progress.ProgressFeatureSettings; @@ -105,7 +106,8 @@ public static Pair create( Configuration neo4jConfiguration, GlobalProcedures globalProcedures, Optional> algorithmProcessingTemplateDecorator, - Optional> catalogFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, ExporterBuildersProviderService exporterBuildersProviderService, MetricsFacade metricsFacade, ModelCatalog modelCatalog, @@ -147,7 +149,8 @@ public static Pair create( var graphDataScienceProviderFactory = GraphDataScienceProviderFactory.create( log, algorithmProcessingTemplateDecorator, - catalogFacadeDecorator, + graphCatalogApplicationsDecorator, + modelCatalogApplicationsDecorator, exporterBuildersProviderService, memoryGauge, metricsFacade, diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProvider.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProvider.java index 8aac310bc6..5973dc6939 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProvider.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProvider.java @@ -25,7 +25,8 @@ import org.neo4j.gds.applications.algorithms.machinery.MemoryGuard; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.applications.algorithms.machinery.WriteContext; -import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; +import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; +import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.configuration.DefaultsConfiguration; import org.neo4j.gds.configuration.LimitsConfiguration; import org.neo4j.gds.core.loading.GraphStoreCatalogService; @@ -37,7 +38,7 @@ import org.neo4j.gds.metrics.procedures.DeprecatedProceduresMetricService; import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.procedures.AlgorithmProcedureFacadeBuilderFactory; -import org.neo4j.gds.procedures.CatalogProcedureFacadeFactory; +import org.neo4j.gds.procedures.GraphCatalogProcedureFacadeFactory; import org.neo4j.gds.procedures.DatabaseIdAccessor; import org.neo4j.gds.procedures.ExporterBuildersProviderService; import org.neo4j.gds.procedures.GraphDataScienceProcedures; @@ -73,8 +74,9 @@ public class GraphDataScienceProvider implements ThrowingFunction> algorithmProcessingTemplateDecorator; - private final Optional> catalogBusinessFacadeDecorator; - private final CatalogProcedureFacadeFactory catalogProcedureFacadeFactory; + private final Optional> graphCatalogApplicationsDecorator; + private final Optional> modelCatalogApplicationsDecorator; + private final GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory; private final DeprecatedProceduresMetricService deprecatedProceduresMetricService; private final ExporterBuildersProviderService exporterBuildersProviderService; private final GraphStoreCatalogService graphStoreCatalogService; @@ -94,8 +96,9 @@ public class GraphDataScienceProvider implements ThrowingFunction> algorithmProcessingTemplateDecorator, - Optional> catalogBusinessFacadeDecorator, - CatalogProcedureFacadeFactory catalogProcedureFacadeFactory, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, + GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory, DeprecatedProceduresMetricService deprecatedProceduresMetricService, ExporterBuildersProviderService exporterBuildersProviderService, GraphStoreCatalogService graphStoreCatalogService, @@ -114,8 +117,9 @@ public class GraphDataScienceProvider implements ThrowingFunction> algorithmProcessingTemplateDecorator; - private final Optional> catalogBusinessFacadeDecorator; + private final Optional> graphCatalogApplicationsDecorator; + private final Optional> modelCatalogApplicationsDecorator; private final ExporterBuildersProviderService exporterBuildersProviderService; private final MemoryGauge memoryGauge; private final MetricsFacade metricsFacade; @@ -70,7 +72,8 @@ final class GraphDataScienceProviderFactory { private GraphDataScienceProviderFactory( Log log, Optional> algorithmProcessingTemplateDecorator, - Optional> catalogBusinessFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, ExporterBuildersProviderService exporterBuildersProviderService, MemoryGauge memoryGauge, MetricsFacade metricsFacade, @@ -80,7 +83,8 @@ private GraphDataScienceProviderFactory( ) { this.log = log; this.algorithmProcessingTemplateDecorator = algorithmProcessingTemplateDecorator; - this.catalogBusinessFacadeDecorator = catalogBusinessFacadeDecorator; + this.graphCatalogApplicationsDecorator = graphCatalogApplicationsDecorator; + this.modelCatalogApplicationsDecorator = modelCatalogApplicationsDecorator; this.exporterBuildersProviderService = exporterBuildersProviderService; this.memoryGauge = memoryGauge; this.metricsFacade = metricsFacade; @@ -95,7 +99,7 @@ GraphDataScienceProvider createGraphDataScienceProvider( boolean useMaxMemoryEstimation, UserLogServices userLogServices ) { - var catalogProcedureFacadeFactory = new CatalogProcedureFacadeFactory(log); + var catalogProcedureFacadeFactory = new GraphCatalogProcedureFacadeFactory(log); var algorithmFacadeBuilderFactory = createAlgorithmFacadeBuilderFactory( graphStoreCatalogService @@ -110,7 +114,8 @@ GraphDataScienceProvider createGraphDataScienceProvider( algorithmFacadeBuilderFactory, metricsFacade.algorithmMetrics(), algorithmProcessingTemplateDecorator, - catalogBusinessFacadeDecorator, + graphCatalogApplicationsDecorator, + modelCatalogApplicationsDecorator, catalogProcedureFacadeFactory, metricsFacade.deprecatedProcedures(), exporterBuildersProviderService, @@ -129,7 +134,8 @@ GraphDataScienceProvider createGraphDataScienceProvider( static GraphDataScienceProviderFactory create( Log log, Optional> algorithmProcessingTemplateDecorator, - Optional> catalogBusinessFacadeDecorator, + Optional> graphCatalogApplicationsDecorator, + Optional> modelCatalogApplicationsDecorator, ExporterBuildersProviderService exporterBuildersProviderService, MemoryGauge memoryGauge, MetricsFacade metricsFacade, @@ -140,7 +146,8 @@ static GraphDataScienceProviderFactory create( return new GraphDataScienceProviderFactory( log, algorithmProcessingTemplateDecorator, - catalogBusinessFacadeDecorator, + graphCatalogApplicationsDecorator, + modelCatalogApplicationsDecorator, exporterBuildersProviderService, memoryGauge, metricsFacade, diff --git a/procedures/model-catalog-facade/build.gradle b/procedures/model-catalog-facade/build.gradle new file mode 100644 index 0000000000..cc75571d0d --- /dev/null +++ b/procedures/model-catalog-facade/build.gradle @@ -0,0 +1,11 @@ +apply plugin: 'java-library' + +description = 'Neo4j Graph Data Science :: Model Catalog Procedure Facade' + +group = 'org.neo4j.gds' + +dependencies { + implementation project(':annotations') + implementation project(':applications-facade') + implementation project(':model-catalog-applications') +} diff --git a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java new file mode 100644 index 0000000000..6c322e671c --- /dev/null +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java @@ -0,0 +1,43 @@ +/* + * 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.procedures.modelcatalog; + +import org.neo4j.gds.applications.ApplicationsFacade; +import org.neo4j.gds.applications.modelcatalog.ModelExistsResult; + +import java.util.stream.Stream; + +public class ModelCatalogProcedureFacade { + private final ModelNameValidationService modelNameValidationService = new ModelNameValidationService(); + + private final ApplicationsFacade applicationsFacade; + + public ModelCatalogProcedureFacade(ApplicationsFacade applicationsFacade) { + this.applicationsFacade = applicationsFacade; + } + + public Stream exists(String modelNameAsString) { + var modelName = modelNameValidationService.validate(modelNameAsString); + + var result = applicationsFacade.modelCatalog().exists(modelName); + + return Stream.of(result); + } +} diff --git a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java new file mode 100644 index 0000000000..5e3a2b7752 --- /dev/null +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java @@ -0,0 +1,34 @@ +/* + * 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.procedures.modelcatalog; + +import org.neo4j.gds.applications.modelcatalog.ModelName; +import org.neo4j.gds.core.CypherMapAccess; + +/** + * A very dull utility + */ +class ModelNameValidationService { + ModelName validate(String modelNameAsString) { + CypherMapAccess.failOnBlank("modelName", modelNameAsString); + + return ModelName.parse(modelNameAsString); + } +} diff --git a/settings.gradle b/settings.gradle index 687836255d..a266afc0b0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -101,6 +101,9 @@ project(':executor').projectDir = file('executor') include('graph-store-catalog-applications') project(':graph-store-catalog-applications').projectDir = file('applications/graph-store-catalog') +include('model-catalog-applications') +project(':model-catalog-applications').projectDir = file('applications/model-catalog') + include('centrality-algorithms') project(':centrality-algorithms').projectDir = file('applications/algorithms/centrality') @@ -269,6 +272,12 @@ project(':algorithms-procedure-facade').projectDir = file('procedures/algorithms include('operations-procedure-facade') project(':operations-procedure-facade').projectDir = file('procedures/operations-facade') +include 'graph-catalog-procedure-facade' +project(':graph-catalog-procedure-facade').projectDir = file('procedures/graph-catalog-facade') + +include 'model-catalog-procedure-facade' +project(':model-catalog-procedure-facade').projectDir = file('procedures/model-catalog-facade') + include('progress-tracking') project(':progress-tracking').projectDir = file('progress-tracking') From 14bb999d16c8e8fbf9bea6c4935e1f3111f90756 Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Mon, 5 Aug 2024 14:47:54 +0200 Subject: [PATCH 2/7] move user log store queries to operations, add operations applications module --- alpha/alpha-proc/build.gradle | 1 + .../org/neo4j/gds/userlog/UserLogProc.java | 2 +- .../neo4j/gds/userlog/UserLogProcTest.java | 8 +-- applications/facade/build.gradle | 1 + .../gds/applications/ApplicationsFacade.java | 11 ++++ .../ApplicationsFacadeBuilder.java | 8 +++ applications/operations/build.gradle | 11 ++++ .../operations/OperationsApplications.java | 47 ++++++++++++++ .../GraphDataScienceProcedures.java | 2 +- procedures/graph-catalog-facade/build.gradle | 1 + .../catalog/GraphCatalogProcedureFacade.java | 8 --- .../GraphCatalogProcedureFacadeTest.java | 43 ------------- procedures/operations-facade/build.gradle | 15 +++++ .../operations/OperationsProcedureFacade.java | 14 ++++- .../OperationsProcedureFacadeTest.java | 63 +++++++++++++++++++ settings.gradle | 3 + 16 files changed, 180 insertions(+), 58 deletions(-) create mode 100644 applications/operations/build.gradle create mode 100644 applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java create mode 100644 procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java diff --git a/alpha/alpha-proc/build.gradle b/alpha/alpha-proc/build.gradle index 8e2db80bfc..a6c10c7d41 100644 --- a/alpha/alpha-proc/build.gradle +++ b/alpha/alpha-proc/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation project(':legacy-cypher-projection') implementation project(':memory-usage') implementation project(':neo4j-api') + implementation project(':operations-procedure-facade') implementation project(':opengds-procedure-facade') implementation project(':pregel') implementation project(':proc-catalog') diff --git a/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java b/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java index 9f3a167378..0804a107eb 100644 --- a/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java +++ b/alpha/alpha-proc/src/main/java/org/neo4j/gds/userlog/UserLogProc.java @@ -51,7 +51,7 @@ public UserLogProc() {} @Procedure("gds.userLog") @Description("Log warnings and hints for currently running tasks.") public Stream queryUserLog(@Name(value = "jobId", defaultValue = "") String jobId) { - return facade.graphCatalog().queryUserLog(jobId); + return facade.operations().queryUserLog(jobId); } @Procedure(value = "gds.alpha.userLog", deprecatedBy = "gds.userLog") diff --git a/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java b/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java index 4a301fd58b..5af12dbeb8 100644 --- a/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java +++ b/alpha/alpha-proc/src/test/java/org/neo4j/gds/userlog/UserLogProcTest.java @@ -24,7 +24,7 @@ import org.neo4j.gds.core.utils.progress.tasks.LeafTask; import org.neo4j.gds.core.utils.warnings.UserLogEntry; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.catalog.GraphCatalogProcedureFacade; +import org.neo4j.gds.procedures.operations.OperationsProcedureFacade; import java.util.stream.Stream; @@ -43,9 +43,9 @@ void shouldLogUserWarnings() { new UserLogEntry(new LeafTask("lt", 87), "going twice..."), new UserLogEntry(new LeafTask("lt", 23), "gone!") ); - var catalogFacade = mock(GraphCatalogProcedureFacade.class); - when(facade.graphCatalog()).thenReturn(catalogFacade); - when(catalogFacade.queryUserLog("unused")).thenReturn(expectedWarnings); + var operationsProcedureFacade = mock(OperationsProcedureFacade.class); + when(facade.operations()).thenReturn(operationsProcedureFacade); + when(operationsProcedureFacade.queryUserLog("unused")).thenReturn(expectedWarnings); var actualWarnings = userLogProc.queryUserLog("unused"); assertThat(actualWarnings).isSameAs(expectedWarnings); diff --git a/applications/facade/build.gradle b/applications/facade/build.gradle index c2af37e7bf..ff5e157178 100644 --- a/applications/facade/build.gradle +++ b/applications/facade/build.gradle @@ -19,6 +19,7 @@ dependencies { implementation project(":model-catalog-applications") implementation project(":miscellaneous-algorithms") implementation project(":node-embedding-algorithms") + implementation project(":operations-applications") implementation project(":path-finding-algorithms") implementation project(":progress-tracking") implementation project(":similarity-algorithms") diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java index e71cf15fcd..0ec91abdfc 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java @@ -40,6 +40,7 @@ import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.DefaultModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; +import org.neo4j.gds.applications.operations.OperationsApplications; import org.neo4j.gds.core.loading.GraphStoreCatalogService; import org.neo4j.gds.core.model.ModelCatalog; import org.neo4j.gds.logging.Log; @@ -64,6 +65,7 @@ public final class ApplicationsFacade { private final MiscellaneousApplications miscellaneousApplications; private final ModelCatalogApplications modelCatalogApplications; private final NodeEmbeddingApplications nodeEmbeddingApplications; + private final OperationsApplications operationsApplications; private final PathFindingApplications pathFindingApplications; private final SimilarityApplications similarityApplications; @@ -74,6 +76,7 @@ public final class ApplicationsFacade { MiscellaneousApplications miscellaneousApplications, ModelCatalogApplications modelCatalogApplications, NodeEmbeddingApplications nodeEmbeddingApplications, + OperationsApplications operationsApplications, PathFindingApplications pathFindingApplications, SimilarityApplications similarityApplications ) { @@ -83,6 +86,7 @@ public final class ApplicationsFacade { this.miscellaneousApplications = miscellaneousApplications; this.modelCatalogApplications = modelCatalogApplications; this.nodeEmbeddingApplications = nodeEmbeddingApplications; + this.operationsApplications = operationsApplications; this.pathFindingApplications = pathFindingApplications; this.similarityApplications = similarityApplications; } @@ -183,6 +187,8 @@ public static ApplicationsFacade create( graphSageModelRepository ); + var operationsApplications = OperationsApplications.create(requestScopedDependencies); + var pathFindingApplications = PathFindingApplications.create( log, requestScopedDependencies, @@ -210,6 +216,7 @@ public static ApplicationsFacade create( .with(miscellaneousApplications) .with(modelCatalogApplications) .with(nodeEmbeddingApplications) + .with(operationsApplications) .with(pathFindingApplications) .with(similarityApplications) .build(); @@ -292,6 +299,10 @@ public NodeEmbeddingApplications nodeEmbeddings() { return nodeEmbeddingApplications; } + public OperationsApplications operations() { + return operationsApplications; + } + public PathFindingApplications pathFinding() { return pathFindingApplications; } diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java index c6c92d0485..01f8efe6ea 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacadeBuilder.java @@ -27,6 +27,7 @@ import org.neo4j.gds.applications.algorithms.similarity.SimilarityApplications; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; +import org.neo4j.gds.applications.operations.OperationsApplications; /** * This is a helper that makes it easy to inject constituents, and to not have to inject all of them. @@ -38,6 +39,7 @@ public class ApplicationsFacadeBuilder { private MiscellaneousApplications miscellaneousApplications; private ModelCatalogApplications modelCatalogApplications; private NodeEmbeddingApplications nodeEmbeddingApplications; + private OperationsApplications operationsApplications; private PathFindingApplications pathFindingApplications; private SimilarityApplications similarityApplications; @@ -71,6 +73,11 @@ public ApplicationsFacadeBuilder with(NodeEmbeddingApplications nodeEmbeddingApp return this; } + public ApplicationsFacadeBuilder with(OperationsApplications operationsApplications) { + this.operationsApplications = operationsApplications; + return this; + } + public ApplicationsFacadeBuilder with(PathFindingApplications pathFindingApplications) { this.pathFindingApplications = pathFindingApplications; return this; @@ -89,6 +96,7 @@ public ApplicationsFacade build() { miscellaneousApplications, modelCatalogApplications, nodeEmbeddingApplications, + operationsApplications, pathFindingApplications, similarityApplications ); diff --git a/applications/operations/build.gradle b/applications/operations/build.gradle new file mode 100644 index 0000000000..1b71591b8a --- /dev/null +++ b/applications/operations/build.gradle @@ -0,0 +1,11 @@ +apply plugin: 'java-library' + +description = 'Neo4j Graph Data Science :: Operations Applications' + +group = 'org.neo4j.gds' + +dependencies { + implementation project(":algorithms-machinery") + implementation project(":core") + implementation project(":progress-tracking") +} diff --git a/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java new file mode 100644 index 0000000000..648794bfca --- /dev/null +++ b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java @@ -0,0 +1,47 @@ +/* + * 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.applications.operations; + +import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; +import org.neo4j.gds.core.utils.warnings.UserLogEntry; + +import java.util.stream.Stream; + +public final class OperationsApplications { + private final RequestScopedDependencies requestScopedDependencies; + + private OperationsApplications(RequestScopedDependencies requestScopedDependencies) { + this.requestScopedDependencies = requestScopedDependencies; + } + + public static OperationsApplications create(RequestScopedDependencies requestScopedDependencies) { + return new OperationsApplications(requestScopedDependencies); + } + + /** + * Huh, we never did jobId filtering... + */ + public Stream queryUserLog(String jobId) { + var user = requestScopedDependencies.getUser(); + var userLogStore = requestScopedDependencies.getUserLogStore(); + + return userLogStore.query(user.getUsername()); + } +} diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java index 7f1852cc8e..6af9ce3d5d 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java @@ -154,7 +154,7 @@ public static GraphDataScienceProcedures create( var pathFindingProcedureFacade = algorithmProcedureFacadeBuilder.createPathFindingProcedureFacade(); var similarityProcedureFacade = algorithmProcedureFacadeBuilder.createSimilarityProcedureFacade(); - var operationsProcedureFacade = new OperationsProcedureFacade(requestScopedDependencies); + var operationsProcedureFacade = new OperationsProcedureFacade(requestScopedDependencies, applicationsFacade); var pipelinesProcedureFacade = new PipelinesProcedureFacade(requestScopedDependencies.getUser()); diff --git a/procedures/graph-catalog-facade/build.gradle b/procedures/graph-catalog-facade/build.gradle index 74b71389ce..1907bd4140 100644 --- a/procedures/graph-catalog-facade/build.gradle +++ b/procedures/graph-catalog-facade/build.gradle @@ -30,6 +30,7 @@ dependencies { implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':node-embedding-algorithms') + implementation project(':operations-applications') implementation project(':path-finding-algorithms') implementation project(':progress-tracking') implementation project(':similarity-algorithms') diff --git a/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java index 95d0881265..56da64ea8c 100644 --- a/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java +++ b/procedures/graph-catalog-facade/src/main/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacade.java @@ -44,7 +44,6 @@ import org.neo4j.gds.beta.filter.GraphFilterResult; import org.neo4j.gds.core.loading.GraphDropNodePropertiesResult; import org.neo4j.gds.core.loading.GraphDropRelationshipResult; -import org.neo4j.gds.core.utils.warnings.UserLogEntry; import org.neo4j.gds.legacycypherprojection.GraphProjectCypherResult; import org.neo4j.gds.projection.GraphProjectNativeResult; import org.neo4j.gds.transaction.TransactionContext; @@ -134,13 +133,6 @@ public boolean graphExists(String graphName) { ); } - /** - * Huh, we never did jobId filtering... - */ - public Stream queryUserLog(String jobId) { - return requestScopedDependencies.getUserLogStore().query(requestScopedDependencies.getUser().getUsername()); - } - /** * @param failIfMissing enable validation that graphs exist before dropping them * @param databaseName optional override diff --git a/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java index 165e7a0acb..dee38a3085 100644 --- a/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java +++ b/procedures/graph-catalog-facade/src/test/java/org/neo4j/gds/procedures/catalog/GraphCatalogProcedureFacadeTest.java @@ -53,9 +53,6 @@ import org.neo4j.gds.core.loading.DeletionResult; import org.neo4j.gds.core.loading.GraphStoreCatalogEntry; import org.neo4j.gds.core.loading.SingleTypeRelationships; -import org.neo4j.gds.core.utils.progress.tasks.LeafTask; -import org.neo4j.gds.core.utils.warnings.UserLogEntry; -import org.neo4j.gds.core.utils.warnings.UserLogStore; import java.time.ZonedDateTime; import java.util.Collection; @@ -63,7 +60,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -97,45 +93,6 @@ void shouldDetermineIfGraphExists() { ); } - /** - * This is a lot of dependency mocking, sure; but that is the nature of this facade, it interacts with Neo4j's - * integration points and distills domain concepts: database and user. It then uses those to interact with domain - * services, the user log in this case. - *

- * How many of these will we need to gain confidence? - * Might we engineer some reuse or commonality out so that we can test this once but have it apply across the board? - * Sure! That's just us engineering. - */ - @Test - void shouldQueryUserLog() { - var userLogStore = mock(UserLogStore.class); - var businessFacade = mock(GraphCatalogApplications.class); - var catalogFacade = new GraphCatalogProcedureFacade( - RequestScopedDependencies.builder() - .with(DatabaseId.of("current database")) - .with(new User("current user", false)) - .with(userLogStore) - .build(), - null, - null, - null, - null, - new ApplicationsFacadeBuilder().with(businessFacade).build(), - WriteContext.builder().build(), - null - ); - - var expectedWarnings = Stream.of( - new UserLogEntry(new LeafTask("lt", 42), "going once"), - new UserLogEntry(new LeafTask("lt", 87), "going twice..."), - new UserLogEntry(new LeafTask("lt", 23), "gone!") - ); - when(userLogStore.query("current user")).thenReturn(expectedWarnings); - var actualWarnings = catalogFacade.queryUserLog(null); - - assertThat(actualWarnings).isSameAs(expectedWarnings); - } - @Test void shouldListGraphsWithoutDegreeDistribution() { var procedureReturnColumns = mock(ProcedureReturnColumns.class); diff --git a/procedures/operations-facade/build.gradle b/procedures/operations-facade/build.gradle index ace544461c..b18a76c2a7 100644 --- a/procedures/operations-facade/build.gradle +++ b/procedures/operations-facade/build.gradle @@ -9,13 +9,26 @@ dependencies { compileOnly(group: 'org.neo4j', name: it, version: ver.'neo4j') { transitive = false } + + testImplementation(group: 'org.neo4j', name: it, version: ver.'neo4j') } implementation project(':algorithms-machinery') + implementation project(':applications-facade') + implementation project(':centrality-algorithms') + implementation project(':community-algorithms') implementation project(':core') implementation project(':core-utils') + implementation project(':graph-store-catalog-applications') + implementation project(':miscellaneous-algorithms') + implementation project(':model-catalog-applications') + implementation project(':operations-applications') + implementation project(':node-embedding-algorithms') + implementation project(':path-finding-algorithms') implementation project(':progress-tracking') + implementation project(':similarity-algorithms') implementation project(':string-formatting') + implementation project(':termination') testImplementation platform(openGds.junit5bom) testImplementation openGds.junit5.jupiter.api @@ -23,4 +36,6 @@ dependencies { testRuntimeOnly openGds.junit5.jupiter.engine testImplementation openGds.assertj.core + + testImplementation openGds.mockito.junit.jupiter } diff --git a/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java index f528734369..3bcb0053d2 100644 --- a/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java +++ b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java @@ -19,10 +19,12 @@ */ package org.neo4j.gds.procedures.operations; +import org.neo4j.gds.applications.ApplicationsFacade; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.core.utils.progress.JobId; import org.neo4j.gds.core.utils.progress.TaskStore; import org.neo4j.gds.core.utils.progress.tasks.TaskTraversal; +import org.neo4j.gds.core.utils.warnings.UserLogEntry; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -32,8 +34,14 @@ public class OperationsProcedureFacade { private final RequestScopedDependencies requestScopedDependencies; - public OperationsProcedureFacade(RequestScopedDependencies requestScopedDependencies) { + private final ApplicationsFacade applicationsFacade; + + public OperationsProcedureFacade( + RequestScopedDependencies requestScopedDependencies, + ApplicationsFacade applicationsFacade + ) { this.requestScopedDependencies = requestScopedDependencies; + this.applicationsFacade = applicationsFacade; } public Stream listProgress(String jobId) { @@ -42,6 +50,10 @@ public Stream listProgress(String jobId) { : jobDetailView(jobId); } + public Stream queryUserLog(String jobId) { + return applicationsFacade.operations().queryUserLog(jobId); + } + private Stream jobsSummaryView() { var taskStore = requestScopedDependencies.getTaskStore(); var user = requestScopedDependencies.getUser(); diff --git a/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java b/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java new file mode 100644 index 0000000000..4d2cf75327 --- /dev/null +++ b/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java @@ -0,0 +1,63 @@ +/* + * 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.procedures.operations; + +import org.junit.jupiter.api.Test; +import org.neo4j.gds.api.DatabaseId; +import org.neo4j.gds.api.User; +import org.neo4j.gds.applications.ApplicationsFacadeBuilder; +import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; +import org.neo4j.gds.applications.operations.OperationsApplications; +import org.neo4j.gds.core.utils.progress.tasks.LeafTask; +import org.neo4j.gds.core.utils.warnings.UserLogEntry; +import org.neo4j.gds.core.utils.warnings.UserLogStore; + +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class OperationsProcedureFacadeTest { + @Test + void shouldQueryUserLog() { + var userLogStore = mock(UserLogStore.class); + var operationsApplications = mock(OperationsApplications.class); + var operationsProcedureFacade = new OperationsProcedureFacade( + RequestScopedDependencies.builder() + .with(DatabaseId.of("current database")) + .with(new User("current user", false)) + .with(userLogStore) + .build(), + new ApplicationsFacadeBuilder().with(operationsApplications).build() + ); + + var expectedWarnings = Stream.of( + new UserLogEntry(new LeafTask("lt", 42), "going once"), + new UserLogEntry(new LeafTask("lt", 87), "going twice..."), + new UserLogEntry(new LeafTask("lt", 23), "gone!") + ); + when(userLogStore.query("current user")).thenReturn(expectedWarnings); + var actualWarnings = operationsProcedureFacade.queryUserLog(null); + + assertThat(actualWarnings).isSameAs(expectedWarnings); + } + +} diff --git a/settings.gradle b/settings.gradle index a266afc0b0..830ea4b136 100644 --- a/settings.gradle +++ b/settings.gradle @@ -104,6 +104,9 @@ project(':graph-store-catalog-applications').projectDir = file('applications/gra include('model-catalog-applications') project(':model-catalog-applications').projectDir = file('applications/model-catalog') +include('operations-applications') +project(':operations-applications').projectDir = file('applications/operations') + include('centrality-algorithms') project(':centrality-algorithms').projectDir = file('applications/algorithms/centrality') From 948098e50fe5253aebc56282bcf1749784fde3fe Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Mon, 5 Aug 2024 16:25:45 +0200 Subject: [PATCH 3/7] move list progress to operations applications module --- .../operations/OperationsApplications.java | 32 +++++++++ .../operations/ResultRenderer.java | 31 ++++++++ .../GraphDataScienceProcedures.java | 2 +- .../operations/DefaultResultRenderer.java | 72 +++++++++++++++++++ .../operations/OperationsProcedureFacade.java | 71 ++++-------------- .../OperationsProcedureFacadeTest.java | 11 ++- 6 files changed, 153 insertions(+), 66 deletions(-) create mode 100644 applications/operations/src/main/java/org/neo4j/gds/applications/operations/ResultRenderer.java create mode 100644 procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/DefaultResultRenderer.java diff --git a/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java index 648794bfca..a85282d5df 100644 --- a/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java +++ b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/OperationsApplications.java @@ -20,6 +20,8 @@ package org.neo4j.gds.applications.operations; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; +import org.neo4j.gds.core.utils.progress.JobId; +import org.neo4j.gds.core.utils.progress.TaskStore; import org.neo4j.gds.core.utils.warnings.UserLogEntry; import java.util.stream.Stream; @@ -35,6 +37,36 @@ public static OperationsApplications create(RequestScopedDependencies requestSco return new OperationsApplications(requestScopedDependencies); } + /** + * List progress for the given user, or for all users if in administrator mode + */ + public Stream listProgress() { + var taskStore = requestScopedDependencies.getTaskStore(); + var user = requestScopedDependencies.getUser(); + + if (user.isAdmin()) return taskStore.query(); + + return taskStore.query(user.getUsername()); + } + + /** + * List progress for the given job id, subject to user permissions. + */ + public Stream listProgress(JobId jobId, ResultRenderer resultRenderer) { + var taskStore = requestScopedDependencies.getTaskStore(); + var user = requestScopedDependencies.getUser(); + + if (user.isAdmin()) { + var results = taskStore.query(jobId); + + return resultRenderer.renderAdministratorView(results); + } + + var results = taskStore.query(user.getUsername(), jobId); + + return resultRenderer.render(results); + } + /** * Huh, we never did jobId filtering... */ diff --git a/applications/operations/src/main/java/org/neo4j/gds/applications/operations/ResultRenderer.java b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/ResultRenderer.java new file mode 100644 index 0000000000..5d0e1c41d0 --- /dev/null +++ b/applications/operations/src/main/java/org/neo4j/gds/applications/operations/ResultRenderer.java @@ -0,0 +1,31 @@ +/* + * 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.applications.operations; + +import org.neo4j.gds.core.utils.progress.TaskStore; + +import java.util.Optional; +import java.util.stream.Stream; + +public interface ResultRenderer { + Stream renderAdministratorView(Stream results); + + Stream render(Optional results); +} diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java index 6af9ce3d5d..f4255d304e 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/GraphDataScienceProcedures.java @@ -154,7 +154,7 @@ public static GraphDataScienceProcedures create( var pathFindingProcedureFacade = algorithmProcedureFacadeBuilder.createPathFindingProcedureFacade(); var similarityProcedureFacade = algorithmProcedureFacadeBuilder.createSimilarityProcedureFacade(); - var operationsProcedureFacade = new OperationsProcedureFacade(requestScopedDependencies, applicationsFacade); + var operationsProcedureFacade = new OperationsProcedureFacade(applicationsFacade); var pipelinesProcedureFacade = new PipelinesProcedureFacade(requestScopedDependencies.getUser()); diff --git a/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/DefaultResultRenderer.java b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/DefaultResultRenderer.java new file mode 100644 index 0000000000..6d1b4629be --- /dev/null +++ b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/DefaultResultRenderer.java @@ -0,0 +1,72 @@ +/* + * 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.procedures.operations; + +import org.neo4j.gds.applications.operations.ResultRenderer; +import org.neo4j.gds.core.utils.progress.JobId; +import org.neo4j.gds.core.utils.progress.TaskStore; +import org.neo4j.gds.core.utils.progress.tasks.TaskTraversal; + +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.neo4j.gds.utils.StringFormatting.formatWithLocale; + +class DefaultResultRenderer implements ResultRenderer { + private final JobId jobId; + + DefaultResultRenderer(JobId jobId) { + this.jobId = jobId; + } + + @Override + public Stream renderAdministratorView(Stream results) { + var progressResultStream = results.flatMap(this::jobProgress); + + var progressResults = progressResultStream.collect(Collectors.toList()); + + if (progressResults.isEmpty()) throw createException(); + + return progressResults.stream(); + } + + @Override + public Stream render(Optional results) { + return results + .map(this::jobProgress) + .orElseThrow(this::createException); + } + + private IllegalArgumentException createException() { + return new IllegalArgumentException( + formatWithLocale( + "No task with job id `%s` was found.", + jobId + ) + ); + } + + private Stream jobProgress(TaskStore.UserTask userTask) { + var jobProgressVisitor = new JobProgressVisitor(userTask.jobId(), userTask.username()); + TaskTraversal.visitPreOrderWithDepth(userTask.task(), jobProgressVisitor); + return jobProgressVisitor.progressRowsStream(); + } +} diff --git a/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java index 3bcb0053d2..2afe79af4a 100644 --- a/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java +++ b/procedures/operations-facade/src/main/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacade.java @@ -20,84 +20,39 @@ package org.neo4j.gds.procedures.operations; import org.neo4j.gds.applications.ApplicationsFacade; -import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; import org.neo4j.gds.core.utils.progress.JobId; -import org.neo4j.gds.core.utils.progress.TaskStore; -import org.neo4j.gds.core.utils.progress.tasks.TaskTraversal; import org.neo4j.gds.core.utils.warnings.UserLogEntry; -import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.neo4j.gds.utils.StringFormatting.formatWithLocale; - public class OperationsProcedureFacade { - private final RequestScopedDependencies requestScopedDependencies; - private final ApplicationsFacade applicationsFacade; - public OperationsProcedureFacade( - RequestScopedDependencies requestScopedDependencies, - ApplicationsFacade applicationsFacade - ) { - this.requestScopedDependencies = requestScopedDependencies; + public OperationsProcedureFacade(ApplicationsFacade applicationsFacade) { this.applicationsFacade = applicationsFacade; } - public Stream listProgress(String jobId) { - return jobId.isBlank() - ? jobsSummaryView() - : jobDetailView(jobId); + public Stream listProgress(String jobIdAsString) { + if (jobIdAsString.isBlank()) return summaryView(); + + var jobId = new JobId(jobIdAsString); + + return detailView(jobId); } public Stream queryUserLog(String jobId) { return applicationsFacade.operations().queryUserLog(jobId); } - private Stream jobsSummaryView() { - var taskStore = requestScopedDependencies.getTaskStore(); - var user = requestScopedDependencies.getUser(); + private Stream detailView(JobId jobId) { + var resultRenderer = new DefaultResultRenderer(jobId); - if (user.isAdmin()) { - return taskStore.query().map(ProgressResult::fromTaskStoreEntry); - } else { - return taskStore.query(user.getUsername()).map(ProgressResult::fromTaskStoreEntry); - } + return applicationsFacade.operations().listProgress(jobId, resultRenderer); } - private Stream jobDetailView(String jobIdAsString) { - var jobId = new JobId(jobIdAsString); - - var taskStore = requestScopedDependencies.getTaskStore(); - var user = requestScopedDependencies.getUser(); - - if (user.isAdmin()) { - var progressResults = taskStore - .query(jobId) - .flatMap(this::jobProgress) - .collect(Collectors.toList()); - - if (progressResults.isEmpty()) { - throw new IllegalArgumentException(formatWithLocale( - "No task with job id `%s` was found.", - jobIdAsString - )); - } - - return progressResults.stream(); - } else { - return taskStore.query(user.getUsername(), jobId).map(this::jobProgress).orElseThrow( - () -> new IllegalArgumentException(formatWithLocale( - "No task with job id `%s` was found.", - jobIdAsString - )) - ); - } - } + private Stream summaryView() { + var results = applicationsFacade.operations().listProgress(); - private Stream jobProgress(TaskStore.UserTask userTask) { - var jobProgressVisitor = new JobProgressVisitor(userTask.jobId(), userTask.username()); - TaskTraversal.visitPreOrderWithDepth(userTask.task(), jobProgressVisitor); - return jobProgressVisitor.progressRowsStream(); + return results.map(ProgressResult::fromTaskStoreEntry); } } diff --git a/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java b/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java index 4d2cf75327..6c5ac27fcc 100644 --- a/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java +++ b/procedures/operations-facade/src/test/java/org/neo4j/gds/procedures/operations/OperationsProcedureFacadeTest.java @@ -20,7 +20,6 @@ package org.neo4j.gds.procedures.operations; import org.junit.jupiter.api.Test; -import org.neo4j.gds.api.DatabaseId; import org.neo4j.gds.api.User; import org.neo4j.gds.applications.ApplicationsFacadeBuilder; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; @@ -39,15 +38,14 @@ class OperationsProcedureFacadeTest { @Test void shouldQueryUserLog() { var userLogStore = mock(UserLogStore.class); - var operationsApplications = mock(OperationsApplications.class); - var operationsProcedureFacade = new OperationsProcedureFacade( + var operationsApplications = OperationsApplications.create( RequestScopedDependencies.builder() - .with(DatabaseId.of("current database")) .with(new User("current user", false)) .with(userLogStore) - .build(), - new ApplicationsFacadeBuilder().with(operationsApplications).build() + .build() ); + var applicationsFacade = new ApplicationsFacadeBuilder().with(operationsApplications).build(); + var operationsProcedureFacade = new OperationsProcedureFacade(applicationsFacade); var expectedWarnings = Stream.of( new UserLogEntry(new LeafTask("lt", 42), "going once"), @@ -59,5 +57,4 @@ void shouldQueryUserLog() { assertThat(actualWarnings).isSameAs(expectedWarnings); } - } From 357a01ad516833f2d35d02ec1a2d587c00dbfd0f Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Mon, 5 Aug 2024 16:48:30 +0200 Subject: [PATCH 4/7] migrate model drop --- .../DefaultModelCatalogApplications.java | 7 +++++ .../ModelCatalogApplications.java | 4 +++ .../model/catalog/BetaModelCatalogResult.java | 2 ++ .../gds/model/catalog/ModelDropProc.java | 30 +++++++------------ .../gds/model/catalog/ModelListProc.java | 2 +- procedures/model-catalog-facade/build.gradle | 3 ++ .../ModelCatalogProcedureFacade.java | 8 +++++ .../modelcatalog}/ModelCatalogResult.java | 3 +- 8 files changed, 36 insertions(+), 23 deletions(-) rename {proc/catalog/src/main/java/org/neo4j/gds/model/catalog => procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog}/ModelCatalogResult.java (96%) diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java index bedc3bbe3e..b13d2c7925 100644 --- a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java @@ -38,6 +38,13 @@ public static DefaultModelCatalogApplications create(ModelCatalog modelCatalog, return new DefaultModelCatalogApplications(modelCatalog, user); } + @Override + public Model drop(ModelName modelName, boolean failIfMissing) { + if (failIfMissing) return modelCatalog.dropOrThrow(user.getUsername(), modelName.getValue()); + + return modelCatalog.drop(user.getUsername(), modelName.getValue()); + } + @Override public ModelExistsResult exists(ModelName modelName) { var untypedModel = modelCatalog.getUntyped(user.getUsername(), modelName.getValue()); diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java index 720701115e..34c8e96493 100644 --- a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java @@ -19,6 +19,10 @@ */ package org.neo4j.gds.applications.modelcatalog; +import org.neo4j.gds.core.model.Model; + public interface ModelCatalogApplications { + Model drop(ModelName modelName, boolean failIfMissing); + ModelExistsResult exists(ModelName modelName); } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/BetaModelCatalogResult.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/BetaModelCatalogResult.java index 4b166a4303..327bcd5ea7 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/BetaModelCatalogResult.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/BetaModelCatalogResult.java @@ -19,6 +19,8 @@ */ package org.neo4j.gds.model.catalog; +import org.neo4j.gds.procedures.modelcatalog.ModelCatalogResult; + import java.time.ZonedDateTime; import java.util.Map; import java.util.stream.Collectors; diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelDropProc.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelDropProc.java index 5db115751c..2e51f774c7 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelDropProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelDropProc.java @@ -19,7 +19,9 @@ */ package org.neo4j.gds.model.catalog; -import org.neo4j.gds.core.model.Model; +import org.neo4j.gds.procedures.GraphDataScienceProcedures; +import org.neo4j.gds.procedures.modelcatalog.ModelCatalogResult; +import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Internal; import org.neo4j.procedure.Name; @@ -29,27 +31,19 @@ import static org.neo4j.procedure.Mode.READ; -public class ModelDropProc extends ModelCatalogProc { - +public class ModelDropProc { private static final String DESCRIPTION = "Drops a loaded model and frees up the resources it occupies."; + @Context + public GraphDataScienceProcedures facade; + @Procedure(name = "gds.model.drop", mode = READ) @Description(DESCRIPTION) public Stream drop( @Name(value = "modelName") String modelName, @Name(value = "failIfMissing", defaultValue = "true") boolean failIfMissing ) { - validateModelName(modelName); - - Model model; - - var modelCatalog = executionContext().modelCatalog(); - if (failIfMissing) { - model = modelCatalog.dropOrThrow(username(), modelName); - } else { - model = modelCatalog.drop(username(), modelName); - } - return Stream.ofNullable(model).map(ModelCatalogResult::new); + return facade.modelCatalog().drop(modelName, failIfMissing); } @Procedure(name = "gds.beta.model.drop", mode = READ, deprecatedBy = "gds.model.drop") @@ -60,13 +54,9 @@ public Stream betaDrop( @Name(value = "modelName") String modelName, @Name(value = "failIfMissing", defaultValue = "true") boolean failIfMissing ) { - executionContext() - .metricsFacade() - .deprecatedProcedures().called("gds.beta.model.drop"); + facade.deprecatedProcedures().called("gds.beta.model.drop"); + facade.log().warn("Procedure `gds.beta.model.drop` has been deprecated, please use `gds.model.drop`."); - executionContext() - .log() - .warn("Procedure `gds.beta.model.drop` has been deprecated, please use `gds.model.drop`."); return drop(modelName, failIfMissing).map(BetaModelCatalogResult::new); } } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java index 232fbb8553..2181619f4b 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java @@ -20,6 +20,7 @@ package org.neo4j.gds.model.catalog; import org.neo4j.gds.core.model.ModelCatalog; +import org.neo4j.gds.procedures.modelcatalog.ModelCatalogResult; import org.neo4j.procedure.Description; import org.neo4j.procedure.Internal; import org.neo4j.procedure.Name; @@ -30,7 +31,6 @@ import static org.neo4j.procedure.Mode.READ; public class ModelListProc extends ModelCatalogProc { - private static final String DESCRIPTION = "Lists all models contained in the model catalog."; @Procedure(name = "gds.model.list", mode = READ) diff --git a/procedures/model-catalog-facade/build.gradle b/procedures/model-catalog-facade/build.gradle index cc75571d0d..aba4069c64 100644 --- a/procedures/model-catalog-facade/build.gradle +++ b/procedures/model-catalog-facade/build.gradle @@ -7,5 +7,8 @@ group = 'org.neo4j.gds' dependencies { implementation project(':annotations') implementation project(':applications-facade') + implementation project(':config-api') + implementation project(':graph-schema-api') + implementation project(':model-catalog-api') implementation project(':model-catalog-applications') } diff --git a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java index 6c322e671c..070bb3d31c 100644 --- a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java @@ -33,6 +33,14 @@ public ModelCatalogProcedureFacade(ApplicationsFacade applicationsFacade) { this.applicationsFacade = applicationsFacade; } + public Stream drop(String modelNameAsString, boolean failIfMissing) { + var modelName = modelNameValidationService.validate(modelNameAsString); + + var model = applicationsFacade.modelCatalog().drop(modelName, failIfMissing); + + return Stream.ofNullable(model).map(ModelCatalogResult::new); + } + public Stream exists(String modelNameAsString) { var modelName = modelNameValidationService.validate(modelNameAsString); diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogResult.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogResult.java similarity index 96% rename from proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogResult.java rename to procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogResult.java index 69b36c6bb0..2672e85bb2 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogResult.java +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogResult.java @@ -17,14 +17,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.gds.model.catalog; +package org.neo4j.gds.procedures.modelcatalog; import org.neo4j.gds.core.model.Model; import java.time.ZonedDateTime; import java.util.Map; -@SuppressWarnings("unused") public class ModelCatalogResult { public final String modelName; public final String modelType; From 463ed8b8f5d11e639fdfae0b1814d1dfdcdcba67 Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Tue, 6 Aug 2024 14:08:56 +0200 Subject: [PATCH 5/7] migrate model list --- .../DefaultModelCatalogApplications.java | 11 +++++ .../ModelCatalogApplications.java | 6 +++ .../gds/model/catalog/ModelCatalogProc.java | 43 ------------------- .../gds/model/catalog/ModelListProc.java | 30 +++++-------- .../ModelCatalogProcedureFacade.java | 26 +++++++++++ 5 files changed, 53 insertions(+), 63 deletions(-) delete mode 100644 proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogProc.java diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java index b13d2c7925..b420b284eb 100644 --- a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/DefaultModelCatalogApplications.java @@ -23,6 +23,7 @@ import org.neo4j.gds.core.model.Model; import org.neo4j.gds.core.model.ModelCatalog; +import java.util.Collection; import java.util.Optional; public final class DefaultModelCatalogApplications implements ModelCatalogApplications { @@ -55,4 +56,14 @@ public ModelExistsResult exists(ModelName modelName) { return new ModelExistsResult(modelName.getValue(), modelType, exists); } + + @Override + public Collection> list() { + return modelCatalog.list(user.getUsername()); + } + + @Override + public Model lookup(ModelName modelName) { + return modelCatalog.getUntyped(user.getUsername(), modelName.getValue()); + } } diff --git a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java index 34c8e96493..453ae56aee 100644 --- a/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java +++ b/applications/model-catalog/src/main/java/org/neo4j/gds/applications/modelcatalog/ModelCatalogApplications.java @@ -21,8 +21,14 @@ import org.neo4j.gds.core.model.Model; +import java.util.Collection; + public interface ModelCatalogApplications { Model drop(ModelName modelName, boolean failIfMissing); ModelExistsResult exists(ModelName modelName); + + Collection> list(); + + Model lookup(ModelName modelName); } diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogProc.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogProc.java deleted file mode 100644 index 43463ba7e6..0000000000 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelCatalogProc.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.model.catalog; - -import org.neo4j.gds.BaseProc; -import org.neo4j.gds.core.CypherMapAccess; -import org.neo4j.gds.core.model.ModelCatalog; -import org.neo4j.gds.executor.ExecutionContext; -import org.neo4j.procedure.Context; - -public abstract class ModelCatalogProc extends BaseProc { - - @Context - public ModelCatalog internalModelCatalog; - - static final String NO_VALUE = "__NO_VALUE"; - - void validateModelName(String modelName) { - CypherMapAccess.failOnBlank("modelName", modelName); - } - - @Override - public ExecutionContext executionContext() { - return super.executionContext().withModelCatalog(internalModelCatalog); - } -} diff --git a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java index 2181619f4b..602dcc3d02 100644 --- a/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java +++ b/proc/catalog/src/main/java/org/neo4j/gds/model/catalog/ModelListProc.java @@ -19,8 +19,9 @@ */ package org.neo4j.gds.model.catalog; -import org.neo4j.gds.core.model.ModelCatalog; +import org.neo4j.gds.procedures.GraphDataScienceProcedures; import org.neo4j.gds.procedures.modelcatalog.ModelCatalogResult; +import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Internal; import org.neo4j.procedure.Name; @@ -28,25 +29,19 @@ import java.util.stream.Stream; +import static org.neo4j.gds.procedures.modelcatalog.ModelCatalogProcedureFacade.NO_VALUE; import static org.neo4j.procedure.Mode.READ; -public class ModelListProc extends ModelCatalogProc { +public class ModelListProc { private static final String DESCRIPTION = "Lists all models contained in the model catalog."; + @Context + public GraphDataScienceProcedures facade; + @Procedure(name = "gds.model.list", mode = READ) @Description(DESCRIPTION) public Stream list(@Name(value = "modelName", defaultValue = NO_VALUE) String modelName) { - ModelCatalog modelCatalog = executionContext().modelCatalog(); - if (modelName == null || modelName.equals(NO_VALUE)) { - var models = modelCatalog.list(username()); - return models.stream().map(ModelCatalogResult::new); - } else { - validateModelName(modelName); - var model = modelCatalog.getUntyped(username(), modelName); - return model == null - ? Stream.empty() - : Stream.of(new ModelCatalogResult(model)); - } + return facade.modelCatalog().list(modelName); } @Procedure(name = "gds.beta.model.list", mode = READ, deprecatedBy = "gds.model.list") @@ -54,13 +49,8 @@ public Stream list(@Name(value = "modelName", defaultValue = @Deprecated @Internal public Stream betaList(@Name(value = "modelName", defaultValue = NO_VALUE) String modelName) { - executionContext() - .metricsFacade() - .deprecatedProcedures().called("gds.beta.model.list"); - - executionContext() - .log() - .warn("Procedure `gds.beta.model.list` has been deprecated, please use `gds.model.list`."); + facade.deprecatedProcedures().called("gds.beta.model.list"); + facade.log().warn("Procedure `gds.beta.model.list` has been deprecated, please use `gds.model.list`."); return list(modelName).map(BetaModelCatalogResult::new); } diff --git a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java index 070bb3d31c..77595bd3f7 100644 --- a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelCatalogProcedureFacade.java @@ -25,6 +25,8 @@ import java.util.stream.Stream; public class ModelCatalogProcedureFacade { + public static final String NO_VALUE = "__NO_VALUE"; + private final ModelNameValidationService modelNameValidationService = new ModelNameValidationService(); private final ApplicationsFacade applicationsFacade; @@ -48,4 +50,28 @@ public Stream exists(String modelNameAsString) { return Stream.of(result); } + + public Stream list(String modelName) { + if (modelName == null || modelName.equals(NO_VALUE)) return list(); + + return lookup(modelName); + } + + private Stream list() { + var models = applicationsFacade.modelCatalog().list(); + + return models.stream().map(ModelCatalogResult::new); + } + + private Stream lookup(String modelNameAsString) { + var modelName = modelNameValidationService.validate(modelNameAsString); + + var model = applicationsFacade.modelCatalog().lookup(modelName); + + if (model == null) return Stream.empty(); + + var result = new ModelCatalogResult(model); + + return Stream.of(result); + } } From 87fefb0f16ef4665fb42bc897b884f326bf7b66b Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Wed, 7 Aug 2024 09:02:58 +0200 Subject: [PATCH 6/7] migrate model publish --- .../procedures/modelcatalog/ModelNameValidationService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java index 5e3a2b7752..6baa7fdee2 100644 --- a/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java +++ b/procedures/model-catalog-facade/src/main/java/org/neo4j/gds/procedures/modelcatalog/ModelNameValidationService.java @@ -25,8 +25,8 @@ /** * A very dull utility */ -class ModelNameValidationService { - ModelName validate(String modelNameAsString) { +public class ModelNameValidationService { + public ModelName validate(String modelNameAsString) { CypherMapAccess.failOnBlank("modelName", modelNameAsString); return ModelName.parse(modelNameAsString); From b91afecf5553b308d54b2201cf17e9b60a295976 Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Wed, 7 Aug 2024 13:35:25 +0200 Subject: [PATCH 7/7] revert to fix tests --- .../java/org/neo4j/gds/ListProgressProc.java | 171 +++++++++++++++++- 1 file changed, 162 insertions(+), 9 deletions(-) diff --git a/proc/misc/src/main/java/org/neo4j/gds/ListProgressProc.java b/proc/misc/src/main/java/org/neo4j/gds/ListProgressProc.java index f24d95fae9..7505742a44 100644 --- a/proc/misc/src/main/java/org/neo4j/gds/ListProgressProc.java +++ b/proc/misc/src/main/java/org/neo4j/gds/ListProgressProc.java @@ -19,36 +19,189 @@ */ package org.neo4j.gds; -import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.operations.ProgressResult; +import org.apache.commons.lang3.time.DurationFormatUtils; +import org.neo4j.gds.core.utils.ClockService; +import org.neo4j.gds.core.utils.progress.JobId; +import org.neo4j.gds.core.utils.progress.TaskStore; +import org.neo4j.gds.core.utils.progress.tasks.DepthAwareTaskVisitor; +import org.neo4j.gds.core.utils.progress.tasks.Task; +import org.neo4j.gds.core.utils.progress.tasks.TaskTraversal; +import org.neo4j.gds.procedures.operations.StructuredOutputHelper; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Internal; import org.neo4j.procedure.Name; import org.neo4j.procedure.Procedure; +import org.neo4j.values.storable.LocalTimeValue; +import java.time.Instant; +import java.time.LocalTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import java.util.stream.Stream; -public class ListProgressProc { +import static org.neo4j.gds.utils.StringFormatting.formatWithLocale; + +public class ListProgressProc extends BaseProc { + static final int PROGRESS_BAR_LENGTH = 10; private static final String DESCRIPTION = "List progress events for currently running tasks."; @Context - public GraphDataScienceProcedures facade; + public TaskStore taskStore; @Internal @Deprecated(forRemoval = true) @Procedure(value = "gds.beta.listProgress", deprecatedBy = "gds.listProgress") @Description(DESCRIPTION) - public Stream betaListProgress(@Name(value = "jobId", defaultValue = "") String jobId) { - facade.deprecatedProcedures().called("gds.beta.listProgress"); - facade.log().warn("Procedure `gds.beta.listProgress` has been deprecated, please use `gds.listProgress`."); + public Stream betaListProgress( + @Name(value = "jobId", defaultValue = "") String jobId + ) { + executionContext() + .metricsFacade() + .deprecatedProcedures().called("gds.beta.listProgress"); + + executionContext() + .log() + .warn("Procedure `gds.beta.listProgress` has been deprecated, please use `gds.listProgress`."); return listProgress(jobId); } @Procedure("gds.listProgress") @Description(DESCRIPTION) - public Stream listProgress(@Name(value = "jobId", defaultValue = "") String jobId) { - return facade.operations().listProgress(jobId); + public Stream listProgress( + @Name(value = "jobId", defaultValue = "") String jobId + ) { + return jobId.isBlank() + ? jobsSummaryView() + : jobDetailView(jobId); + } + + private Stream jobsSummaryView() { + if (isGdsAdmin()) { + return taskStore.query().map(ProgressResult::fromTaskStoreEntry); + } else { + return taskStore.query(username()).map(ProgressResult::fromTaskStoreEntry); + } + } + + private Stream jobDetailView(String jobIdAsString) { + var jobId = new JobId(jobIdAsString); + + if (isGdsAdmin()) { + var progressResults = taskStore + .query(jobId) + .flatMap(ListProgressProc::jobProgress) + .collect(Collectors.toList()); + + if (progressResults.isEmpty()) { + throw new IllegalArgumentException(formatWithLocale( + "No task with job id `%s` was found.", + jobIdAsString + )); + } + + return progressResults.stream(); + } else { + return taskStore.query(username(), jobId).map(ListProgressProc::jobProgress).orElseThrow( + () -> new IllegalArgumentException(formatWithLocale( + "No task with job id `%s` was found.", + jobIdAsString + )) + ); + } + } + + private static Stream jobProgress(TaskStore.UserTask userTask) { + var jobProgressVisitor = new JobProgressVisitor(userTask.jobId(), userTask.username()); + TaskTraversal.visitPreOrderWithDepth(userTask.task(), jobProgressVisitor); + return jobProgressVisitor.progressRowsStream(); + } + + @SuppressWarnings("unused") + public static class ProgressResult { + public String username; + public String jobId; + public String taskName; + public String progress; + public String progressBar; + public String status; + public LocalTimeValue timeStarted; + public String elapsedTime; + + static ProgressResult fromTaskStoreEntry(String username, Map.Entry taskStoreEntry) { + var jobId = taskStoreEntry.getKey(); + var task = taskStoreEntry.getValue(); + return new ProgressResult(username, task, jobId, task.description()); + } + + static ProgressResult fromTaskStoreEntry(TaskStore.UserTask userTask) { + return new ProgressResult(userTask.username(), userTask.task(), userTask.jobId(), userTask.task().description()); + } + + static ProgressResult fromTaskWithDepth(String username, Task task, JobId jobId, int depth) { + var treeViewTaskName = StructuredOutputHelper.treeViewDescription(task.description(), depth); + return new ProgressResult(username, task, jobId, treeViewTaskName); + } + + public ProgressResult(String username, Task task, JobId jobId, String taskName) { + var progressContainer = task.getProgress(); + + this.jobId = jobId.asString(); + this.taskName = taskName; + this.username = username; + this.progress = StructuredOutputHelper.computeProgress(progressContainer); + this.progressBar = StructuredOutputHelper.progressBar(progressContainer, PROGRESS_BAR_LENGTH); + this.status = task.status().name(); + this.timeStarted = localTimeValue(task); + this.elapsedTime = prettyElapsedTime(task); + } + + private LocalTimeValue localTimeValue(Task task) { + if (task.hasNotStarted()) { + return null; + } + return LocalTimeValue.localTime(LocalTime.ofInstant( + Instant.ofEpochMilli(task.startTime()), + ZoneId.systemDefault() + )); + } + + private String prettyElapsedTime(Task task) { + if (task.hasNotStarted()) { + return "Not yet started"; + } + var finishTime = task.finishTime(); + var finishTimeOrNow = finishTime != -1 + ? finishTime + : ClockService.clock().millis(); + var elapsedTime = finishTimeOrNow - task.startTime(); + return DurationFormatUtils.formatDurationWords(elapsedTime, true, true); + } + } + + public static class JobProgressVisitor extends DepthAwareTaskVisitor { + + private final JobId jobId; + private final String username; + private final List progressRows; + + JobProgressVisitor(JobId jobId, String username) { + this.jobId = jobId; + this.username = username; + this.progressRows = new ArrayList<>(); + } + + Stream progressRowsStream() { + return this.progressRows.stream(); + } + + @Override + public void visit(Task task) { + progressRows.add(ProgressResult.fromTaskWithDepth(username, task, jobId, depth())); + } } }