This is an automated email from the ASF dual-hosted git repository. florianhockmann pushed a commit to branch TINKERPOP-2471 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 46309b507db784ff482d57748565a35b3534b5cb Author: Florian Hockmann <[email protected]> AuthorDate: Wed Oct 12 14:16:45 2022 +0200 TINKERPOP-2471 Add logging to .NET --- CHANGELOG.asciidoc | 1 + docs/src/reference/gremlin-variants.asciidoc | 11 ++++ docs/src/upgrade/release-3.5.x.asciidoc | 18 ++++++ .../Gremlin.Net.Template.csproj | 3 +- gremlin-dotnet/src/Gremlin.Net.Template/Program.cs | 22 ++++--- .../src/Gremlin.Net/Driver/ConnectionPool.cs | 16 ++++- .../src/Gremlin.Net/Driver/GremlinClient.cs | 23 +++++-- .../src/Gremlin.Net/Driver/IGremlinClient.cs | 1 - gremlin-dotnet/src/Gremlin.Net/Driver/Log.cs | 46 ++++++++++++++ .../Driver/Remote/DriverRemoteConnection.cs | 71 ++++++++++++---------- gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj | 3 +- .../src/Gremlin.Net/Process/Traversal/Bytecode.cs | 6 ++ .../Gremlin.Net/Process/Traversal/Instruction.cs | 2 +- gremlin-dotnet/src/pom.xml | 2 +- .../Docs/Reference/GremlinVariantsTests.cs | 15 ++++- .../Gremlin.Net.IntegrationTest.csproj | 1 + .../Driver/ConnectionPoolTests.cs | 12 ++-- .../Process/Traversal/BytecodeTests.cs | 11 ++++ 18 files changed, 200 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 579c005883..6496cc4e67 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -34,6 +34,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Changed `JavaTranslator` exception handling so that an `IllegalArgumentException` is used for cases where the method exists but the signature can't be discerned given the arguments supplied. * Dockerized all test environment for .NET, JavaScript, Python, Go, and Python-based tests for Console, and added Docker as a build requirement. * Bumped to `snakeyaml` 1.32 to fix security vulnerability. +* Added logging in .NET. ==== Bugs diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc index 60e5bdd406..2670e75777 100644 --- a/docs/src/reference/gremlin-variants.asciidoc +++ b/docs/src/reference/gremlin-variants.asciidoc @@ -1145,6 +1145,17 @@ attacks like CRIME/BREACH. Compression should therefore be turned off if the app server as well as data that could potentially be controlled by an untrusted user. Compression can be disabled via the `disableCompression` parameter. +[[gremlin-dotnet-logging]] +=== Logging + +It is possible to enable logging for the Gremlin.Net driver by providing an `ILoggerFactory` (from the +`Microsoft.Extensions.Logging.Abstractions` package) to the `GremlinClient` constructor: + +[source,csharp] +---- +include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs[tags=logging] +---- + [[gremlin-dotnet-serialization]] === Serialization diff --git a/docs/src/upgrade/release-3.5.x.asciidoc b/docs/src/upgrade/release-3.5.x.asciidoc index 2b4f659ca0..2596d8beba 100644 --- a/docs/src/upgrade/release-3.5.x.asciidoc +++ b/docs/src/upgrade/release-3.5.x.asciidoc @@ -30,7 +30,25 @@ complete list of all the modifications that are part of this release. === Upgrading for Users +==== Gremlin.NET: Add logging +The Gremlin.NET driver can now be configured for logging to get more insights into its internal state, like when +a connection was closed and will therefore be replaced. It uses `Microsoft.Extensions.Logging` for this so all kinds +of different .NET logging implementations can be used. + +The following example shows how to provide a `LoggerFactory` that is configured to log to the console to +`GremlinClient`: + +[source,csharp] +---- +var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddConsole(); +}); +var client = new GremlinClient(new GremlinServer("localhost", 8182), loggerFactory: loggerFactory); +---- + +See: link:https://issues.apache.org/jira/browse/TINKERPOP-2471[TINKERPOP-2471] == TinkerPop 3.5.4 diff --git a/gremlin-dotnet/src/Gremlin.Net.Template/Gremlin.Net.Template.csproj b/gremlin-dotnet/src/Gremlin.Net.Template/Gremlin.Net.Template.csproj index e7ba2b71fa..5ff2dc9fc2 100644 --- a/gremlin-dotnet/src/Gremlin.Net.Template/Gremlin.Net.Template.csproj +++ b/gremlin-dotnet/src/Gremlin.Net.Template/Gremlin.Net.Template.csproj @@ -22,7 +22,8 @@ limitations under the License. <TargetFramework>net6.0</TargetFramework> </PropertyGroup> - <ItemGroup> + <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /> <!-- We need both reference elements until this is resolved: https://github.com/dotnet/sdk/issues/1151 --> <ProjectReference Include="../Gremlin.Net/Gremlin.Net.csproj" /> diff --git a/gremlin-dotnet/src/Gremlin.Net.Template/Program.cs b/gremlin-dotnet/src/Gremlin.Net.Template/Program.cs index 93018e7e5a..42ffb9a255 100644 --- a/gremlin-dotnet/src/Gremlin.Net.Template/Program.cs +++ b/gremlin-dotnet/src/Gremlin.Net.Template/Program.cs @@ -24,8 +24,7 @@ using System; using Gremlin.Net.Driver; using Gremlin.Net.Driver.Remote; -using Gremlin.Net.Structure; - +using Microsoft.Extensions.Logging; using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; namespace Gremlin.Net.Template @@ -37,15 +36,18 @@ namespace Gremlin.Net.Template private static void Main() { - using (var client = new GremlinClient(new GremlinServer(GremlinServerHostname, GremlinServerPort))) + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + }); + using var connection = new DriverRemoteConnection(new GremlinClient( + new GremlinServer(GremlinServerHostname, GremlinServerPort), loggerFactory: loggerFactory)); + var g = Traversal().WithRemote(connection); + var service = new Service(g); + var creators = service.FindCreatorsOfSoftware("lop"); + foreach (var c in creators) { - var g = Traversal().WithRemote(new DriverRemoteConnection(client)); - var service = new Service(g); - var creators = service.FindCreatorsOfSoftware("lop"); - foreach (var c in creators) - { - Console.WriteLine(c); - } + Console.WriteLine(c); } } } diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs index 8273561f53..e4f4a72ae2 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs @@ -28,6 +28,7 @@ using System.Threading; using System.Threading.Tasks; using Gremlin.Net.Driver.Exceptions; using Gremlin.Net.Process; +using Microsoft.Extensions.Logging; using Polly; namespace Gremlin.Net.Driver @@ -42,16 +43,19 @@ namespace Gremlin.Net.Driver private readonly ConcurrentDictionary<IConnection, byte> _deadConnections = new ConcurrentDictionary<IConnection, byte>(); private readonly ConnectionPoolSettings _settings; + private readonly ILogger<ConnectionPool> _logger; private int _connectionIndex; private int _poolState; private const int PoolIdle = 0; private const int PoolPopulationInProgress = 1; private readonly CancellationTokenSource _cts = new CancellationTokenSource(); - public ConnectionPool(IConnectionFactory connectionFactory, ConnectionPoolSettings settings) + public ConnectionPool(IConnectionFactory connectionFactory, ConnectionPoolSettings settings, + ILogger<ConnectionPool> logger) { _connectionFactory = connectionFactory; _settings = settings; + _logger = logger; ReplaceDeadConnectionsAsync().WaitUnwrap(); } @@ -60,7 +64,11 @@ namespace Gremlin.Net.Driver public IConnection GetAvailableConnection() { var connection = Policy.Handle<ServerUnavailableException>() - .WaitAndRetry(_settings.ReconnectionAttempts, ComputeRetrySleepDuration) + .WaitAndRetry(_settings.ReconnectionAttempts, ComputeRetrySleepDuration, onRetry: + (_, _, retryCount, _) => + { + _logger.CouldNotGetConnectionFromPool(retryCount, _settings.ReconnectionAttempts); + }) .Execute(GetConnectionFromPool); return ProxiedConnection(connection); @@ -116,10 +124,11 @@ namespace Gremlin.Net.Driver _deadConnections.Clear(); } - + private async Task FillPoolAsync() { var nrConnectionsToCreate = _settings.PoolSize - _connections.Count; + _logger.FillingPool(nrConnectionsToCreate); var connectionCreationTasks = new List<Task<IConnection>>(nrConnectionsToCreate); try { @@ -218,6 +227,7 @@ namespace Gremlin.Net.Driver private void RemoveConnectionFromPool(IConnection connection) { + _logger.RemovingClosedConnectionFromPool(); _deadConnections.TryAdd(connection, 0); } diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs index 149622e78d..ed801ce4e4 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs @@ -27,6 +27,8 @@ using System.Threading.Tasks; using Gremlin.Net.Driver.Messages; using Gremlin.Net.Structure.IO; using Gremlin.Net.Structure.IO.GraphSON; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Gremlin.Net.Driver { @@ -36,6 +38,8 @@ namespace Gremlin.Net.Driver public class GremlinClient : IGremlinClient { private readonly ConnectionPool _connectionPool; + + internal ILoggerFactory LoggerFactory { get; } /// <summary> /// Initializes a new instance of the <see cref="GremlinClient" /> class for the specified Gremlin Server. @@ -118,8 +122,11 @@ namespace Gremlin.Net.Driver connectionPoolSettings = new ConnectionPoolSettings {PoolSize = 1}; } } - _connectionPool = - new ConnectionPool(connectionFactory, connectionPoolSettings ?? new ConnectionPoolSettings()); + + LoggerFactory = NullLoggerFactory.Instance; + + _connectionPool = new ConnectionPool(connectionFactory, + connectionPoolSettings ?? new ConnectionPoolSettings(), LoggerFactory.CreateLogger<ConnectionPool>()); } private static void VerifyGraphSONArgumentTypeForMimeType<T>(object argument, string argumentName, @@ -149,15 +156,16 @@ namespace Gremlin.Net.Driver /// <param name="disableCompression"> /// Whether to disable compression. Compression is only supported since .NET 6. /// There it is also enabled by default. - /// + /// /// Note that compression might make your application susceptible to attacks like CRIME/BREACH. Compression /// should therefore be turned off if your application sends sensitive data to the server as well as data /// that could potentially be controlled by an untrusted user. /// </param> + /// <param name="loggerFactory">A factory to create loggers. If not provided, then nothing will be logged.</param> public GremlinClient(GremlinServer gremlinServer, IMessageSerializer messageSerializer = null, ConnectionPoolSettings connectionPoolSettings = null, Action<ClientWebSocketOptions> webSocketConfiguration = null, string sessionId = null, - bool disableCompression = false) + bool disableCompression = false, ILoggerFactory loggerFactory = null) { messageSerializer ??= new GraphSON3MessageSerializer(); var webSocketSettings = new WebSocketSettings @@ -184,8 +192,11 @@ namespace Gremlin.Net.Driver connectionPoolSettings = new ConnectionPoolSettings {PoolSize = 1}; } } - _connectionPool = - new ConnectionPool(connectionFactory, connectionPoolSettings ?? new ConnectionPoolSettings()); + + LoggerFactory = loggerFactory ?? NullLoggerFactory.Instance; + + _connectionPool = new ConnectionPool(connectionFactory, + connectionPoolSettings ?? new ConnectionPoolSettings(), LoggerFactory.CreateLogger<ConnectionPool>()); } /// <summary> diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs index 9bef4be409..97baca25d5 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs @@ -22,7 +22,6 @@ #endregion using System; -using System.Collections.Generic; using System.Threading.Tasks; using Gremlin.Net.Driver.Messages; diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Log.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Log.cs new file mode 100644 index 0000000000..ae9c712f82 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Log.cs @@ -0,0 +1,46 @@ +#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.Process.Traversal; +using Microsoft.Extensions.Logging; + +namespace Gremlin.Net.Driver +{ + internal static partial class Log + { + [LoggerMessage(20000, LogLevel.Information, "Creating {nrConnections} new connections")] + public static partial void FillingPool(this ILogger logger, int nrConnections); + + [LoggerMessage(20001, LogLevel.Warning, + "Could not get a connection from the pool. Will try again. Retry {retryCount} of {maxRetries}")] + public static partial void CouldNotGetConnectionFromPool(this ILogger logger, int retryCount, int maxRetries); + + [LoggerMessage(20002, LogLevel.Information, + "A connection was closed. Removing it from the pool so it can be replaced.")] + public static partial void RemovingClosedConnectionFromPool(this ILogger logger); + + [LoggerMessage(20003, LogLevel.Debug, "Submitting Bytecode {bytecode} for request: {requestId}")] + public static partial void SubmittingBytecode(this ILogger logger, Bytecode bytecode, Guid requestId); + } +} \ 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 2f32f778ba..761a85b74a 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs @@ -28,6 +28,8 @@ using Gremlin.Net.Driver.Messages; using Gremlin.Net.Process.Remote; using Gremlin.Net.Process.Traversal; using Gremlin.Net.Process.Traversal.Strategy.Decoration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Gremlin.Net.Driver.Remote { @@ -38,68 +40,69 @@ namespace Gremlin.Net.Driver.Remote { private readonly IGremlinClient _client; private readonly string _traversalSource; - + private readonly ILogger<DriverRemoteConnection> _logger; + /// <summary> /// Filter on these keys provided to OptionsStrategy and apply them to the request. Note that /// "scriptEvaluationTimeout" was deprecated in 3.3.9 but still supported in server implementations and will /// be removed in later versions. /// </summary> - private readonly List<String> _allowedKeys = new List<string> - {Tokens.ArgsEvalTimeout, "scriptEvaluationTimeout", Tokens.ArgsBatchSize, - Tokens.RequestId, Tokens.ArgsUserAgent}; + private readonly List<string> _allowedKeys = new() + { + Tokens.ArgsEvalTimeout, "scriptEvaluationTimeout", Tokens.ArgsBatchSize, + Tokens.RequestId, Tokens.ArgsUserAgent + }; private readonly string _sessionId; private string Processor => IsSessionBound ? Tokens.ProcessorSession : Tokens.ProcessorTraversal; /// <inheritdoc /> public bool IsSessionBound => _sessionId != null; - - /// <summary> - /// Initializes a new <see cref="IRemoteConnection" /> using "g" as the default remote TraversalSource name. - /// </summary> - /// <param name="host">The host to connect to.</param> - /// <param name="port">The port to connect to.</param> - /// <exception cref="ArgumentNullException">Thrown when client is null.</exception> - public DriverRemoteConnection(string host, int port):this(host, port, "g") - { - } - + /// <summary> /// Initializes a new <see cref="IRemoteConnection" />. /// </summary> /// <param name="host">The host to connect to.</param> /// <param name="port">The port to connect to.</param> /// <param name="traversalSource">The name of the traversal source on the server to bind to.</param> + /// <param name="loggerFactory">A factory to create loggers. If not provided, then nothing will be logged.</param> /// <exception cref="ArgumentNullException">Thrown when client is null.</exception> - public DriverRemoteConnection(string host, int port, string traversalSource):this(new GremlinClient(new GremlinServer(host, port)), traversalSource) + public DriverRemoteConnection(string host, int port, string traversalSource = "g", + ILoggerFactory loggerFactory = null) : this( + new GremlinClient(new GremlinServer(host, port), loggerFactory: loggerFactory), traversalSource, + logger: loggerFactory != null + ? loggerFactory.CreateLogger<DriverRemoteConnection>() + : NullLogger<DriverRemoteConnection>.Instance) { } /// <summary> - /// Initializes a new <see cref="IRemoteConnection" /> using "g" as the default remote TraversalSource name. + /// Initializes a new <see cref="IRemoteConnection" />. /// </summary> /// <param name="client">The <see cref="IGremlinClient" /> that will be used for the connection.</param> - /// <exception cref="ArgumentNullException">Thrown when client is null.</exception> - public DriverRemoteConnection(IGremlinClient client):this(client, "g") + /// <param name="traversalSource">The name of the traversal source on the server to bind to.</param> + /// <exception cref="ArgumentNullException">Thrown when client or the traversalSource is null.</exception> + public DriverRemoteConnection(IGremlinClient client, string traversalSource = "g") + : this(client, traversalSource, null) { } - /// <summary> - /// Initializes a new <see cref="IRemoteConnection" />. - /// </summary> - /// <param name="client">The <see cref="IGremlinClient" /> that will be used for the connection.</param> - /// <param name="traversalSource">The name of the traversal source on the server to bind to.</param> - /// <exception cref="ArgumentNullException">Thrown when client is null.</exception> - public DriverRemoteConnection(IGremlinClient client, string traversalSource) + private DriverRemoteConnection(IGremlinClient client, string traversalSource, string sessionId = null, + ILogger<DriverRemoteConnection> logger = null) { _client = client ?? throw new ArgumentNullException(nameof(client)); _traversalSource = traversalSource ?? throw new ArgumentNullException(nameof(traversalSource)); - } - private DriverRemoteConnection(IGremlinClient client, string traversalSource, Guid sessionId) - : this(client, traversalSource) - { - _sessionId = sessionId.ToString(); + if (logger == null) + { + var loggerFactory = client is GremlinClient gremlinClient + ? gremlinClient.LoggerFactory + : NullLoggerFactory.Instance; + + logger = loggerFactory.CreateLogger<DriverRemoteConnection>(); + } + _logger = logger; + _sessionId = sessionId; } /// <summary> @@ -116,6 +119,8 @@ namespace Gremlin.Net.Driver.Remote private async Task<IEnumerable<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode) { + _logger.SubmittingBytecode(bytecode, requestid); + var requestMsg = RequestMessage.Build(Tokens.OpsBytecode) .Processor(Processor) @@ -141,14 +146,14 @@ namespace Gremlin.Net.Driver.Remote } } } - + return await _client.SubmitAsync<Traverser>(requestMsg.Create()).ConfigureAwait(false); } /// <inheritdoc /> public RemoteTransaction Tx(GraphTraversalSource g) { - var session = new DriverRemoteConnection(_client, _traversalSource, Guid.NewGuid()); + var session = new DriverRemoteConnection(_client, _traversalSource, Guid.NewGuid().ToString(), _logger); return new RemoteTransaction(session, g); } diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj index 9110d4de92..e16d088f73 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj +++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj @@ -21,7 +21,7 @@ limitations under the License. <TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <GenerateDocumentationFile>true</GenerateDocumentationFile> - <LangVersion>8</LangVersion> + <LangVersion>9</LangVersion> </PropertyGroup> <PropertyGroup Label="Package"> @@ -71,6 +71,7 @@ NOTE that versions suffixed with "-rc" are considered release candidates (i.e. p </PropertyGroup> <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" /> <PackageReference Include="System.Text.Json" Version="6.0.6" /> <PackageReference Include="Polly" Version="7.2.3" /> diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs index cd53a1c6c5..e692ed23e2 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Bytecode.cs @@ -168,5 +168,11 @@ namespace Gremlin.Net.Process.Traversal { return type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>); } + + /// <inheritdoc /> + public override string ToString() + { + return $"[[{string.Join(", ", SourceInstructions)}], [{string.Join(", ", StepInstructions)}]]"; + } } } diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs index 1063b33749..b99343ab0b 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs @@ -57,7 +57,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public override string ToString() { - return OperatorName + " [" + String.Join(",", Arguments) + "]"; + return $"{OperatorName}({string.Join(", ", Arguments)})"; } /// <inheritdoc /> diff --git a/gremlin-dotnet/src/pom.xml b/gremlin-dotnet/src/pom.xml index 264196baff..e5ed5985ce 100644 --- a/gremlin-dotnet/src/pom.xml +++ b/gremlin-dotnet/src/pom.xml @@ -61,7 +61,7 @@ limitations under the License. file.write(file.getText("UTF-8").replaceFirst(/<Version>(.*)<\/Version>/, "<Version>" + mavenVersion + "</Version>")) file = new File(platformAgnosticBaseDirPath + "/Gremlin.Net.Template/Gremlin.Net.Template.csproj") - file.write(file.getText("UTF-8").replaceFirst(/Version="(.*)"/, "Version=\"" + mavenVersion + "\"")) + file.write(file.getText("UTF-8").replaceFirst(/Gremlin\.Net\" Version="(.*)"/, "Gremlin.Net\" Version=\"" + mavenVersion + "\"")) file = new File(platformAgnosticBaseDirPath + "/Gremlin.Net.Template/Gremlin.Net.Template.nuspec") file.write(file.getText("UTF-8").replaceFirst(/<version>(.*)<\/version>/, "<version>" + mavenVersion + "</version>")) diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs index fb8479f223..4b277c4f8d 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs @@ -32,6 +32,7 @@ using Gremlin.Net.Process.Traversal.Step.Util; using Gremlin.Net.Process.Traversal.Strategy.Decoration; using Gremlin.Net.Structure.IO.GraphBinary; using Gremlin.Net.Structure.IO.GraphSON; +using Microsoft.Extensions.Logging; using Xunit; // tag::commonImports[] using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource; @@ -58,11 +59,23 @@ namespace Gremlin.Net.IntegrationTest.Docs.Reference public void ConnectingTest() { // tag::connecting[] -var remoteConnection = new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182)), "g"); +using var remoteConnection = new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182)), "g"); var g = Traversal().WithRemote(remoteConnection); // end::connecting[] } + [Fact(Skip="No Server under localhost")] + public void LoggingTest() + { +// tag::logging[] + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + }); + var client = new GremlinClient(new GremlinServer("localhost", 8182), loggerFactory: loggerFactory); +// end::logging[] + } + [Fact(Skip="No Server under localhost")] public void SerializationGraphBinaryTest() { diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj index b779f1e9b6..04c74b9eb6 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj @@ -12,6 +12,7 @@ </ItemGroup> <ItemGroup> <PackageReference Include="gherkin" Version="24.1.0" /> + <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" /> <PackageReference Include="xunit" Version="2.4.2" /> diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs index 53e3506c22..9db8e91aa3 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs @@ -27,6 +27,7 @@ using System.Threading; using System.Threading.Tasks; using Gremlin.Net.Driver; using Gremlin.Net.Driver.Exceptions; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; @@ -389,12 +390,11 @@ namespace Gremlin.Net.UnitTest.Driver private static ConnectionPool CreateConnectionPool(IConnectionFactory connectionFactory, int poolSize = 2, int reconnectionAttempts = 1) { - return new ConnectionPool(connectionFactory, - new ConnectionPoolSettings - { - PoolSize = poolSize, ReconnectionAttempts = reconnectionAttempts, - ReconnectionBaseDelay = TimeSpan.FromMilliseconds(10) // let the tests execute fast - }); + return new ConnectionPool(connectionFactory, new ConnectionPoolSettings + { + PoolSize = poolSize, ReconnectionAttempts = reconnectionAttempts, + ReconnectionBaseDelay = TimeSpan.FromMilliseconds(10) // let the tests execute fast + }, NullLogger<ConnectionPool>.Instance); } } } \ No newline at end of file diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/BytecodeTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/BytecodeTests.cs index 64f2f87c77..5f42b4e648 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/BytecodeTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/BytecodeTests.cs @@ -172,5 +172,16 @@ namespace Gremlin.Net.UnitTest.Process.Traversal var arg = bytecode.SourceInstructions[0].Arguments[0] as ISet<object>; Assert.Equal(new Binding("setVariable", "setValue"), arg.ToList()[1]); } + + [Fact] + public void ShouldIncludeStepAndSourceInstructionsForToString() + { + var bytecode = new Bytecode(); + bytecode.AddSource("source", 1, 2); + bytecode.AddStep("step1", 9, 8); + bytecode.AddStep("step2", 0); + + Assert.Equal("[[source(1, 2)], [step1(9, 8), step2(0)]]", bytecode.ToString()); + } } } \ No newline at end of file
