This is an automated email from the ASF dual-hosted git repository. florianhockmann pushed a commit to branch TINKERPOP-2556 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 43e01dc6897cb80ab42e3cd1a7ed7d46ae35d079 Author: Florian Hockmann <[email protected]> AuthorDate: Fri Oct 8 16:35:31 2021 +0200 TINKERPOP-2556 Basic implementation in place, test still seem to not terminate for some reason --- .github/workflows/build-test.yml | 2 +- .../Driver/Remote/DriverRemoteConnection.cs | 35 +++++- .../Driver/Remote/DriverRemoteTransaction.cs | 69 +++++++++++ gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj | 5 +- .../Process/Remote/IRemoteConnection.cs | 6 + .../src/Gremlin.Net/Process/Traversal/Bytecode.cs | 2 +- .../IRemoteConnection.cs => Traversal/GraphOp.cs} | 26 ++-- .../Process/Traversal/GraphTraversalSource.cs | 32 ++++- .../ITransaction.cs} | 17 +-- .../GraphTraversalModificationTests.cs | 109 ++++++++++++++++ .../DriverRemoteConnection/GraphTraversalTests.cs | 2 +- .../Driver/Remote/DriverRemoteTransactionTests.cs | 57 +++++++++ gremlin-dotnet/test/pom.xml | 137 +++++++++++++++++++++ 13 files changed, 459 insertions(+), 40 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 74e912e..7e25b0f 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -185,4 +185,4 @@ jobs: touch gremlin-dotnet/src/.glv touch gremlin-dotnet/test/.glv mvn clean install -pl -:gremlin-javascript,-:gremlin-python,-:gremlint -q -DskipTests -Dci - mvn verify -pl :gremlin-dotnet,:gremlin-dotnet-tests -P gremlin-dotnet \ No newline at end of file + mvn verify -pl :gremlin-dotnet,:gremlin-dotnet-tests -P gremlin-dotnet -DincludeNeo4j \ No newline at end of file diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs index 006cf8a..63649a1 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs @@ -25,10 +25,10 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Gremlin.Net.Driver.Messages; -using Gremlin.Net.Driver; using Gremlin.Net.Process.Remote; using Gremlin.Net.Process.Traversal; using Gremlin.Net.Process.Traversal.Strategy.Decoration; +using Gremlin.Net.Structure; namespace Gremlin.Net.Driver.Remote { @@ -49,6 +49,10 @@ namespace Gremlin.Net.Driver.Remote {Tokens.ArgsEvalTimeout, "scriptEvaluationTimeout", Tokens.ArgsBatchSize, Tokens.RequestId, Tokens.ArgsUserAgent}; + private readonly string _sessionId; + private string Processor => IsSessionBound ? Tokens.ProcessorSession : Tokens.ProcessorTraversal; + public bool IsSessionBound => _sessionId != null; + /// <summary> /// Initializes a new <see cref="IRemoteConnection" /> using "g" as the default remote TraversalSource name. /// </summary> @@ -91,6 +95,12 @@ namespace Gremlin.Net.Driver.Remote _traversalSource = traversalSource ?? throw new ArgumentNullException(nameof(traversalSource)); } + private DriverRemoteConnection(IGremlinClient client, string traversalSource, Guid sessionId) + : this(client, traversalSource) + { + _sessionId = sessionId.ToString(); + } + /// <summary> /// Submits <see cref="Bytecode" /> for evaluation to a remote Gremlin Server. /// </summary> @@ -107,11 +117,16 @@ namespace Gremlin.Net.Driver.Remote { var requestMsg = RequestMessage.Build(Tokens.OpsBytecode) - .Processor(Tokens.ProcessorTraversal) + .Processor(Processor) .OverrideRequestId(requestid) .AddArgument(Tokens.ArgsGremlin, bytecode) .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", _traversalSource}}); + if (IsSessionBound) + { + requestMsg.AddArgument(Tokens.ArgsSession, _sessionId); + } + var optionsStrategyInst = bytecode.SourceInstructions.Find( s => s.OperatorName == "withStrategies" && s.Arguments[0] is OptionsStrategy); if (optionsStrategyInst != null) @@ -128,6 +143,22 @@ namespace Gremlin.Net.Driver.Remote return await _client.SubmitAsync<Traverser>(requestMsg.Create()).ConfigureAwait(false); } + + public ITransaction Tx(GraphTraversalSource g) + { + var session = new DriverRemoteConnection(_client, _traversalSource, Guid.NewGuid()); + return new DriverRemoteTransaction(session, g); + } + + public async Task CommitAsync() + { + await SubmitAsync<object, object>(GraphOp.Commit).ConfigureAwait(false); + } + + public async Task RollbackAsync() + { + await SubmitAsync<object, object>(GraphOp.Rollback).ConfigureAwait(false); + } /// <inheritdoc /> public void Dispose() diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTransaction.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTransaction.cs new file mode 100644 index 0000000..f3be21b --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTransaction.cs @@ -0,0 +1,69 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Threading.Tasks; +using Gremlin.Net.Process.Traversal; +using Gremlin.Net.Structure; + +namespace Gremlin.Net.Driver.Remote +{ + public class DriverRemoteTransaction : ITransaction, IDisposable + { + private readonly DriverRemoteConnection _sessionBasedConnection; + private GraphTraversalSource _g; + + public DriverRemoteTransaction(DriverRemoteConnection connection, GraphTraversalSource g) + { + _sessionBasedConnection = connection; + _g = g; + } + + public GraphTraversalSource Begin() + { + if (_g.IsSessionBound) + { + throw new InvalidOperationException("Transaction already started on this object"); + } + _g = new GraphTraversalSource(_g.TraversalStrategies, _g.Bytecode, _sessionBasedConnection); + return _g; + } + + public async Task CommitAsync() + { + await _sessionBasedConnection.CommitAsync().ConfigureAwait(false); + Dispose(); + } + + public async Task RollbackAsync() + { + await _sessionBasedConnection.RollbackAsync().ConfigureAwait(false); + Dispose(); + } + + public void Dispose() + { + _sessionBasedConnection.Dispose(); + } + } +} \ No newline at end of file diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj index 0f963bb..f9e3fc5 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj +++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj @@ -19,8 +19,9 @@ limitations under the License. <PropertyGroup Label="Build"> <TargetFramework>netstandard2.0</TargetFramework> - <TreatWarningsAsErrors>true</TreatWarningsAsErrors> - <GenerateDocumentationFile>true</GenerateDocumentationFile> +<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>--> +<!-- <GenerateDocumentationFile>true</GenerateDocumentationFile>--> + <LangVersion>8</LangVersion> </PropertyGroup> <PropertyGroup Label="Package"> diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs index 5393bcb..9502f5d 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs @@ -23,6 +23,7 @@ using System.Threading.Tasks; using Gremlin.Net.Process.Traversal; +using Gremlin.Net.Structure; namespace Gremlin.Net.Process.Remote { @@ -38,5 +39,10 @@ namespace Gremlin.Net.Process.Remote /// <param name="bytecode">The <see cref="Bytecode" /> to send.</param> /// <returns>The <see cref="ITraversal" /> with the results and optional side-effects.</returns> Task<ITraversal<S, E>> SubmitAsync<S, E>(Bytecode bytecode); + + ITransaction Tx(GraphTraversalSource graphTraversalSource); + bool IsSessionBound { get; } + Task CommitAsync(); + Task RollbackAsync(); } } \ No newline at end of file diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs index 7149e8b..cd53a1c 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs @@ -38,7 +38,7 @@ namespace Gremlin.Net.Process.Traversal /// </remarks> public class Bytecode { - private static readonly object[] EmptyArray = new object[0]; + private static readonly object[] EmptyArray = Array.Empty<object>(); /// <summary> /// Initializes a new instance of the <see cref="Bytecode" /> class. diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphOp.cs similarity index 55% copy from gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs copy to gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphOp.cs index 5393bcb..b938541 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphOp.cs @@ -21,22 +21,18 @@ #endregion -using System.Threading.Tasks; -using Gremlin.Net.Process.Traversal; - -namespace Gremlin.Net.Process.Remote +namespace Gremlin.Net.Process.Traversal { - /// <summary> - /// A simple abstraction of a "connection" to a "server". - /// </summary> - public interface IRemoteConnection + public static class GraphOp { - /// <summary> - /// Submits <see cref="ITraversal" /> <see cref="Bytecode" /> to a server and returns a - /// <see cref="ITraversal" />. - /// </summary> - /// <param name="bytecode">The <see cref="Bytecode" /> to send.</param> - /// <returns>The <see cref="ITraversal" /> with the results and optional side-effects.</returns> - Task<ITraversal<S, E>> SubmitAsync<S, E>(Bytecode bytecode); + public static Bytecode Commit { get; } = CreateGraphOp("tx", "commit"); + public static Bytecode Rollback { get; } = CreateGraphOp("tx", "rollback"); + + private static Bytecode CreateGraphOp(string name, object value) + { + var bytecode = new Bytecode(); + bytecode.AddSource(name, value); + return bytecode; + } } } \ No newline at end of file diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs index c74e826..ba31cd7 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs @@ -24,6 +24,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Gremlin.Net.Driver.Remote; using Gremlin.Net.Process.Remote; using Gremlin.Net.Process.Traversal.Strategy.Decoration; using Gremlin.Net.Structure; @@ -38,6 +39,10 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public class GraphTraversalSource { + private readonly IRemoteConnection _connection; + + public bool IsSessionBound => _connection is { IsSessionBound: true }; + /// <summary> /// Gets or sets the traversal strategies associated with this graph traversal source. /// </summary> @@ -71,6 +76,15 @@ namespace Gremlin.Net.Process.Traversal Bytecode = bytecode; } + public GraphTraversalSource(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode, + IRemoteConnection connection) + : this(traversalStrategies.Where(strategy => strategy.GetType() != typeof(RemoteStrategy)).ToList(), + bytecode) + { + _connection = connection; + TraversalStrategies.Add(new RemoteStrategy(connection)); + } + public GraphTraversalSource With(string key) { return With(key, true); @@ -243,12 +257,19 @@ namespace Gremlin.Net.Process.Traversal /// <see cref="GraphTraversal{SType, EType}" />. /// </param> /// <returns>A <see cref="GraphTraversalSource" /> configured to use the provided <see cref="IRemoteConnection" />.</returns> - public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection) + public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection) => + new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies), + new Bytecode(Bytecode), remoteConnection); + + public ITransaction Tx() { - var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies), - new Bytecode(Bytecode)); - source.TraversalStrategies.Add(new RemoteStrategy(remoteConnection)); - return source; + // you can't do g.tx().begin().tx() - no child transactions + if (IsSessionBound) + { + throw new InvalidOperationException( + "This GraphTraversalSource is already bound to a transaction - child transactions are not supported"); + } + return _connection.Tx(this); } /// <summary> @@ -377,7 +398,6 @@ namespace Gremlin.Net.Process.Traversal traversal.Bytecode.AddStep("io", file); return traversal; } - } #pragma warning restore 1591 diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/ITransaction.cs similarity index 59% copy from gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs copy to gremlin-dotnet/src/Gremlin.Net/Structure/ITransaction.cs index 5393bcb..f3dc77e 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Remote/IRemoteConnection.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/ITransaction.cs @@ -24,19 +24,12 @@ using System.Threading.Tasks; using Gremlin.Net.Process.Traversal; -namespace Gremlin.Net.Process.Remote +namespace Gremlin.Net.Structure { - /// <summary> - /// A simple abstraction of a "connection" to a "server". - /// </summary> - public interface IRemoteConnection + public interface ITransaction { - /// <summary> - /// Submits <see cref="ITraversal" /> <see cref="Bytecode" /> to a server and returns a - /// <see cref="ITraversal" />. - /// </summary> - /// <param name="bytecode">The <see cref="Bytecode" /> to send.</param> - /// <returns>The <see cref="ITraversal" /> with the results and optional side-effects.</returns> - Task<ITraversal<S, E>> SubmitAsync<S, E>(Bytecode bytecode); + GraphTraversalSource Begin(); + Task CommitAsync(); + Task RollbackAsync(); } } \ No newline at end of file diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalModificationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalModificationTests.cs new file mode 100644 index 0000000..6089293 --- /dev/null +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalModificationTests.cs @@ -0,0 +1,109 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Threading.Tasks; +using Gremlin.Net.Process.Remote; +using Gremlin.Net.Process.Traversal; +using Xunit; + +namespace Gremlin.Net.IntegrationTest.Process.Traversal.DriverRemoteConnection +{ + public class GraphTraversalModificationTests : IDisposable + { + private readonly IRemoteConnection _connection = new RemoteConnectionFactory().CreateRemoteConnection("g"); + + [IgnoreIfTransactionsNotSupportedFact] + public async Task ShouldSupportRemoteTransactionsCommit() + { + var g = AnonymousTraversalSource.Traversal().WithRemote(_connection); + var tx = g.Tx(); + var gtx = tx.Begin(); + await gtx.AddV("person").Property("name", "florian").Promise(t => t.Iterate()).ConfigureAwait(false); + await gtx.AddV("person").Property("name", "josh").Promise(t => t.Iterate()).ConfigureAwait(false); + + // Assert within the transaction + var count = await gtx.V().Count().Promise(t => t.Next()).ConfigureAwait(false); + Assert.Equal(2, count); + + // Vertices should not be visible in a different transaction before commiting + count = await g.V().Count().Promise(t => t.Next()).ConfigureAwait(false); + Assert.Equal(0, count); + + // Now commit changes to test outside of the transaction + await tx.CommitAsync().ConfigureAwait(false); + + count = await g.V().Count().Promise(t => t.Next()).ConfigureAwait(false); + Assert.Equal(2, count); + + g.V().Count().Next(); + } + + [IgnoreIfTransactionsNotSupportedFact] + public async Task ShouldSupportRemoteTransactionsRollback() + { + var g = AnonymousTraversalSource.Traversal().WithRemote(_connection); + var tx = g.Tx(); + var gtx = tx.Begin(); + await gtx.AddV("person").Property("name", "florian").Promise(t => t.Iterate()).ConfigureAwait(false); + await gtx.AddV("person").Property("name", "josh").Promise(t => t.Iterate()).ConfigureAwait(false); + + // Assert within the transaction + var count = await gtx.V().Count().Promise(t => t.Next()).ConfigureAwait(false); + Assert.Equal(2, count); + + // Now rollback changes to test outside of the transaction + await tx.RollbackAsync().ConfigureAwait(false); + + count = await g.V().Count().Promise(t => t.Next()).ConfigureAwait(false); + Assert.Equal(2, count); + + g.V().Count().Next(); + } + + public void Dispose() + { + EmptyGraph(); + } + + private void EmptyGraph() + { + var g = AnonymousTraversalSource.Traversal().WithRemote(_connection); + g.V().Drop().Iterate(); + } + } + + public sealed class IgnoreIfTransactionsNotSupportedFact : FactAttribute + { + public IgnoreIfTransactionsNotSupportedFact() + { + if (!TransactionsSupported) + { + Skip = "Transactions not supported"; + } + } + + private static bool TransactionsSupported => + Convert.ToBoolean(Environment.GetEnvironmentVariable("TEST_TRANSACTIONS")); + } +} \ No newline at end of file diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs index 89597a3..b0347bc 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs @@ -247,4 +247,4 @@ namespace Gremlin.Net.IntegrationTest.Process.Traversal.DriverRemoteConnection Assert.Equal(6, count); } } -} +} \ No newline at end of file diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Remote/DriverRemoteTransactionTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Remote/DriverRemoteTransactionTests.cs new file mode 100644 index 0000000..51f2fc3 --- /dev/null +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Remote/DriverRemoteTransactionTests.cs @@ -0,0 +1,57 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using Gremlin.Net.Driver; +using Gremlin.Net.Driver.Remote; +using Gremlin.Net.Process.Traversal; +using Moq; +using Xunit; + +namespace Gremlin.Net.UnitTest.Driver.Remote +{ + public class DriverRemoteTransactionTests + { + [Fact] + public void ShouldNotAllowBeginMoreThanOnce() + { + var g = AnonymousTraversalSource.Traversal() + .WithRemote(new DriverRemoteConnection(Mock.Of<IGremlinClient>())); + var tx = g.Tx(); + tx.Begin(); + + Assert.Throws<InvalidOperationException>(() => tx.Begin()); + } + + [Fact] + public void ShouldNotSupportChildTransactions() + { + var g = AnonymousTraversalSource.Traversal() + .WithRemote(new DriverRemoteConnection(Mock.Of<IGremlinClient>())); + var tx = g.Tx(); + + var gtx = tx.Begin(); + Assert.Throws<InvalidOperationException>(() => gtx.Tx()); + } + } +} \ No newline at end of file diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml index d110391..f1be8e2 100644 --- a/gremlin-dotnet/test/pom.xml +++ b/gremlin-dotnet/test/pom.xml @@ -96,6 +96,16 @@ limitations under the License. <extensions>true</extensions> <configuration> <skip>${skipTests}</skip> + <!-- + transaction testing is disabled unless the -DincludeNeo4j flag enables the include-neo4j + maven profile which is a standard profile we use to add neo4j to testing explicitly - for + npm we set this TEST_TRANSACTIONS environment variable that can be accessed in tests to + determine if we skip transaction oriented tests or not. without neo4j we can't test tx() + so this is disabled by default and enabled in the include-neo4j profile below + --> + <environment> + <TEST_TRANSACTIONS>false</TEST_TRANSACTIONS> + </environment> </configuration> </plugin> <plugin> @@ -113,6 +123,11 @@ limitations under the License. <version>${project.version}</version> </dependency> <dependency> + <groupId>org.apache.tinkerpop</groupId> + <artifactId>neo4j-gremlin</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> @@ -206,5 +221,127 @@ limitations under the License. </plugins> </build> </profile> + <!-- + This profile will include neo4j for purposes of transactional testing within Gremlin Server. + Tests that require neo4j specifically will be "ignored" if this profile is not turned on. + --> + <profile> + <id>include-neo4j</id> + <activation> + <activeByDefault>false</activeByDefault> + <property> + <name>includeNeo4j</name> + </property> + </activation> + <properties> + <packaging.type>dotnet-integration-test</packaging.type> + </properties> + <build> + <plugins> + <!-- with neo4j present we can enable transaction testing --> + <plugin> + <groupId>org.eobjects.build</groupId> + <artifactId>dotnet-maven-plugin</artifactId> + <configuration> + <environment> + <TEST_TRANSACTIONS>true</TEST_TRANSACTIONS> + </environment> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.gmavenplus</groupId> + <artifactId>gmavenplus-plugin</artifactId> + <dependencies> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-tinkerpop-api-impl</artifactId> + <version>0.9-3.4.0</version> + <exclusions> + <exclusion> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-kernel</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.commons</groupId> + <artifactId>commons-text</artifactId> + </exclusion> + <exclusion> + <groupId>com.github.ben-manes.caffeine</groupId> + <artifactId>caffeine</artifactId> + </exclusion> + <exclusion> + <groupId>org.scala-lang</groupId> + <artifactId>scala-library</artifactId> + </exclusion> + <exclusion> + <groupId>org.scala-lang</groupId> + <artifactId>scala-reflect</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-nop</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> + </exclusion> + <exclusion> + <groupId>io.dropwizard.metrics</groupId> + <artifactId>metrics-core</artifactId> + </exclusion> + <exclusion> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + </exclusion> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.scala-lang</groupId> + <artifactId>scala-library</artifactId> + <version>2.11.8</version> + </dependency> + <dependency> + <groupId>org.scala-lang</groupId> + <artifactId>scala-reflect</artifactId> + <version>2.11.8</version> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> + <version>5.5.0</version> + </dependency> + <dependency> + <groupId>io.dropwizard.metrics</groupId> + <artifactId>metrics-core</artifactId> + <version>4.0.2</version> + </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-kernel</artifactId> + <version>3.4.11</version> + <exclusions> + <exclusion> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> </profiles> </project> \ No newline at end of file
