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 9ca1366de8..3593945009 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,6 +36,7 @@ import org.neo4j.gds.applications.algorithms.pathfinding.PathFindingApplications; import org.neo4j.gds.applications.algorithms.similarity.SimilarityApplications; import org.neo4j.gds.applications.graphstorecatalog.DefaultGraphCatalogApplications; +import org.neo4j.gds.applications.graphstorecatalog.ExportLocation; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.DefaultModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; @@ -50,10 +51,8 @@ import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; -import java.nio.file.Path; import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; /** * This is the top level facade for GDS applications. If you are integrating GDS, @@ -100,7 +99,7 @@ public final class ApplicationsFacade { */ public static ApplicationsFacade create( Log log, - Supplier exportLocation, + ExportLocation exportLocation, Optional> algorithmProcessingTemplateDecorator, Optional> graphCatalogApplicationsDecorator, Optional> modelCatalogApplicationsDecorator, @@ -256,7 +255,7 @@ private static AlgorithmProcessingTemplate createAlgorithmProcessingTemplate( private static GraphCatalogApplications createGraphCatalogApplications( Log log, - Supplier exportLocation, + ExportLocation exportLocation, GraphStoreCatalogService graphStoreCatalogService, ProjectionMetricsService projectionMetricsService, RequestScopedDependencies requestScopedDependencies, diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java index 6938107331..5e5006285b 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultGraphCatalogApplications.java @@ -50,10 +50,8 @@ import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; -import java.nio.file.Path; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -178,31 +176,9 @@ public class DefaultGraphCatalogApplications implements GraphCatalogApplications this.exportToDatabaseApplication = exportToDatabaseApplication; } - /** - * A special entrypoint for Snowgraph integration, where we are selective about which functionality we touch. - * Case in point, we want Snowgraph to be Neo4j-less. - * We ought to address this later with a more categorical solution. - */ - public static GraphCatalogApplications create( - Log log, - GraphStoreCatalogService graphStoreCatalogService, - ProjectionMetricsService projectionMetricsService, - RequestScopedDependencies requestScopedDependencies - ) { - return create( - log, - null, - graphStoreCatalogService, - projectionMetricsService, - requestScopedDependencies, - null, - null - ); - } - public static GraphCatalogApplications create( Log log, - Supplier exportLocation, + ExportLocation exportLocation, GraphStoreCatalogService graphStoreCatalogService, ProjectionMetricsService projectionMetricsService, RequestScopedDependencies requestScopedDependencies, diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportLocation.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportLocation.java new file mode 100644 index 0000000000..07da28df54 --- /dev/null +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportLocation.java @@ -0,0 +1,33 @@ +/* + * 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.graphstorecatalog; + +import java.nio.file.Path; +import java.util.Optional; + +/** + * There are two flavours of usage: you get the path or die trying; or, + * you get the path and inquire if it is configured. Either case, errors are injected. + */ +public interface ExportLocation { + Path getAcceptingError(); + + Optional getAcceptingNull(); +} diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportToCsvApplication.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportToCsvApplication.java index 9b5b5fb39b..85f2a52743 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportToCsvApplication.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/ExportToCsvApplication.java @@ -36,7 +36,6 @@ import java.nio.file.Path; import java.util.Optional; -import java.util.function.Supplier; import static org.neo4j.gds.core.io.file.GraphStoreExporterUtil.EXPORT_DIR; import static org.neo4j.gds.core.io.file.GraphStoreExporterUtil.exportPath; @@ -47,14 +46,14 @@ class ExportToCsvApplication { private final GraphDatabaseService graphDatabaseService; private final Transaction procedureTransaction; - private final Supplier exportLocation; + private final ExportLocation exportLocation; private final TaskRegistryFactory taskRegistryFactory; ExportToCsvApplication( Log log, GraphDatabaseService graphDatabaseService, Transaction procedureTransaction, - Supplier exportLocation, + ExportLocation exportLocation, TaskRegistryFactory taskRegistryFactory ) { this.log = log; @@ -73,7 +72,7 @@ FileExportResult run(GraphName graphName, GraphStoreToFileExporterConfig configu configuration.batchSize() ); - var exportLocation = this.exportLocation.get(); + var exportLocation = this.exportLocation.getAcceptingError(); var exportDirectory = readyExportDirectory(exportParameters.exportName(), exportLocation); var result = GraphStoreExporterUtil.export( 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 ae2890a7cd..697e6b494d 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 @@ -25,7 +25,7 @@ import org.neo4j.gds.core.write.NativeExportBuildersProvider; import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.procedures.ExporterBuildersProviderService; -import org.neo4j.gds.procedures.integration.ExportLocation; +import org.neo4j.gds.procedures.integration.DefaultExportLocation; import org.neo4j.gds.procedures.integration.OpenGraphDataScienceExtensionBuilder; import org.neo4j.gds.procedures.integration.LogAccessor; import org.neo4j.kernel.api.procedure.GlobalProcedures; @@ -56,7 +56,7 @@ public Lifecycle newInstance(ExtensionContext extensionContext, Dependencies dep // OpenGDS edition customisations go here ExporterBuildersProviderService exporterBuildersProviderService = (__, ___) -> new NativeExportBuildersProvider(); // we always just offer native writes in OpenGDS - var exportLocation = ExportLocation.create(neo4jConfiguration); + var exportLocation = new DefaultExportLocation(log, neo4jConfiguration); var metricsFacade = MetricsFacade.PASSTHROUGH_METRICS_FACADE; // no metrics in OpenGDS var modelCatalog = new OpenModelCatalogProvider().get(null); var graphSageModelRepository = new DisableModelRepository(); // no model storing in OpenGDS 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 c5b64278af..a2a520993d 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 @@ -25,6 +25,7 @@ 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.ExportLocation; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelRepository; @@ -46,10 +47,8 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.kernel.api.KernelTransaction; -import java.nio.file.Path; import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; public class GraphDataScienceProcedures { private final Log log; @@ -89,7 +88,7 @@ public static GraphDataScienceProcedures create( AlgorithmProcedureFacadeBuilderFactory algorithmProcedureFacadeBuilderFactory, DefaultsConfiguration defaultsConfiguration, DeprecatedProceduresMetricService deprecatedProceduresMetricService, - Supplier exportLocation, + ExportLocation exportLocation, GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory, GraphStoreCatalogService graphStoreCatalogService, LimitsConfiguration limitsConfiguration, diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/DefaultExportLocation.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/DefaultExportLocation.java new file mode 100644 index 0000000000..f05da031ff --- /dev/null +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/DefaultExportLocation.java @@ -0,0 +1,64 @@ +/* + * 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.integration; + +import org.neo4j.gds.applications.graphstorecatalog.ExportLocation; +import org.neo4j.gds.logging.Log; +import org.neo4j.gds.settings.GdsSettings; +import org.neo4j.graphdb.config.Configuration; + +import java.nio.file.Path; +import java.util.Optional; + +import static org.neo4j.gds.utils.StringFormatting.formatWithLocale; + +public final class DefaultExportLocation implements ExportLocation { + private final Log log; + private final Configuration neo4jConfiguration; + + public DefaultExportLocation(Log log, Configuration neo4jConfiguration) { + this.log = log; + this.neo4jConfiguration = neo4jConfiguration; + } + + @Override + public Path getAcceptingError() { + var exportLocation = neo4jConfiguration.get(GdsSettings.exportLocation()); + + if (exportLocation == null) throw new IllegalStateException(formatWithLocale( + "The configuration '%s' needs to be set.", + GdsSettings.exportLocation().name() + )); + + return exportLocation; + } + + @Override + public Optional getAcceptingNull() { + var exportLocation = neo4jConfiguration.get(GdsSettings.exportLocation()); + + if (exportLocation == null) log.warn( + "[gds] The configuration %s is missing.", + GdsSettings.exportLocation().name() + ); + + return Optional.ofNullable(exportLocation); + } +} diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExportLocation.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExportLocation.java deleted file mode 100644 index e81d7bee49..0000000000 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExportLocation.java +++ /dev/null @@ -1,48 +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.procedures.integration; - -import org.neo4j.gds.settings.GdsSettings; -import org.neo4j.graphdb.config.Configuration; - -import java.nio.file.Path; -import java.util.function.Supplier; - -import static org.neo4j.gds.utils.StringFormatting.formatWithLocale; - -public final class ExportLocation { - private ExportLocation() {} - - /** - * Right, when I made this eager, 500 tests failed. So indirection it is. - */ - public static Supplier create(Configuration neo4jConfiguration) { - return () -> { - var exportLocation = neo4jConfiguration.get(GdsSettings.exportLocation()); - - if (exportLocation == null) throw new IllegalStateException(formatWithLocale( - "The configuration '%s' needs to be set.", - GdsSettings.exportLocation().name() - )); - - return exportLocation; - }; - } -} diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProvider.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProvider.java index 94d8657245..543f344529 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProvider.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProvider.java @@ -24,6 +24,7 @@ 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.ExportLocation; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelRepository; @@ -54,10 +55,8 @@ import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.procedure.Context; -import java.nio.file.Path; import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; /** * We use this at request time to construct the facade that the procedures call. @@ -78,7 +77,7 @@ public class GraphDataScienceProceduresProvider implements ThrowingFunction exportLocation; + private final ExportLocation exportLocation; private final GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory; private final GraphStoreCatalogService graphStoreCatalogService; private final LimitsConfiguration limitsConfiguration; @@ -102,7 +101,7 @@ public class GraphDataScienceProceduresProvider implements ThrowingFunction exportLocation, + ExportLocation exportLocation, GraphCatalogProcedureFacadeFactory graphCatalogProcedureFacadeFactory, GraphStoreCatalogService graphStoreCatalogService, LimitsConfiguration limitsConfiguration, diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProviderFactory.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProviderFactory.java index db93ca31d6..a52f611b86 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProviderFactory.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/GraphDataScienceProceduresProviderFactory.java @@ -21,6 +21,7 @@ import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate; import org.neo4j.gds.applications.algorithms.machinery.DefaultMemoryGuard; +import org.neo4j.gds.applications.graphstorecatalog.ExportLocation; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelRepository; @@ -39,14 +40,13 @@ import org.neo4j.gds.procedures.UserLogServices; import org.neo4j.graphdb.config.Configuration; -import java.nio.file.Path; import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; /** * This is a way to squirrel away some dull code. * We want to keep Neo4j out from here, this could be reusable. + * PS: _Best_ class name ever, bar none. */ final class GraphDataScienceProceduresProviderFactory { /** @@ -63,7 +63,7 @@ final class GraphDataScienceProceduresProviderFactory { private final Configuration neo4jConfiguration; private final ExporterBuildersProviderService exporterBuildersProviderService; - private final Supplier exportLocation; + private final ExportLocation exportLocation; private final MemoryGauge memoryGauge; private final MetricsFacade metricsFacade; private final ModelCatalog modelCatalog; @@ -76,7 +76,7 @@ final class GraphDataScienceProceduresProviderFactory { Log log, Configuration neo4jConfiguration, ExporterBuildersProviderService exporterBuildersProviderService, - Supplier exportLocation, + ExportLocation exportLocation, MemoryGauge memoryGauge, MetricsFacade metricsFacade, ModelCatalog modelCatalog, diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/OpenGraphDataScienceExtensionBuilder.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/OpenGraphDataScienceExtensionBuilder.java index f048a66dcf..99e3c26aa4 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/OpenGraphDataScienceExtensionBuilder.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/OpenGraphDataScienceExtensionBuilder.java @@ -21,6 +21,7 @@ import org.apache.commons.lang3.tuple.Triple; import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate; +import org.neo4j.gds.applications.graphstorecatalog.ExportLocation; import org.neo4j.gds.applications.graphstorecatalog.GraphCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelCatalogApplications; import org.neo4j.gds.applications.modelcatalog.ModelRepository; @@ -45,11 +46,9 @@ import org.neo4j.kernel.lifecycle.Lifecycle; import java.lang.management.ManagementFactory; -import java.nio.file.Path; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; -import java.util.function.Supplier; /** * The GraphDataScience component has a certain contract, @@ -107,7 +106,8 @@ public static Triple exportLocation, + ExporterBuildersProviderService exporterBuildersProviderService, + ExportLocation exportLocation, MetricsFacade metricsFacade, ModelCatalog modelCatalog, ModelRepository modelRepository,