Skip to content

Commit

Permalink
Notifications config (#691)
Browse files Browse the repository at this point in the history
* Introduce Bolt 5.1 & 5.2
* Introduce Notifications Config
  • Loading branch information
thelonelyvulpes authored Mar 30, 2023
1 parent 1af151a commit df22aeb
Show file tree
Hide file tree
Showing 65 changed files with 1,791 additions and 526 deletions.
31 changes: 26 additions & 5 deletions Neo4j.Driver/Neo4j.Driver.Tests.Integration/Direct/ResultIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,41 @@ public async Task GetSummary()
public async Task ShouldContainsSystemUpdates()
{
// Ensure that a constraint exists
var session = Driver.AsyncSession(ForDatabase("system"));
await using var session = Driver.AsyncSession(x => x.WithDatabase("system"));
Exception error = null;
try
{
var cursor = await session.RunAsync("CREATE USER foo SET PASSWORD 'bar'");
var cursor = await session.RunAsync("CREATE USER foo SET PASSWORD 'zxcvvcxz'");
var summary = await cursor.ConsumeAsync();
summary.Counters.ContainsUpdates.Should().BeFalse();
summary.Counters.ContainsSystemUpdates.Should().BeTrue();
summary.Counters.SystemUpdates.Should().Be(1);
}
catch (Exception ex)
{
error = ex;
}
finally
{
var cursor = await session.RunAsync("DROP USER foo");
await cursor.ConsumeAsync();
await session.CloseAsync();
try
{
var cursor = await session.RunAsync("DROP USER foo");
await cursor.ConsumeAsync();
}
catch (Exception ex)
{
if (error != null)
{
throw new AggregateException(ex, error);
}

throw;
}

if (error != null)
{
throw error;
}
}
}

Expand Down
36 changes: 32 additions & 4 deletions Neo4j.Driver/Neo4j.Driver.Tests.Integration/Reactive/SummaryIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ public void ShouldNotReturnPlanAndProfile()
HasPlan = false, Plan = default(IPlan), HasProfile = false, Profile = default(IProfiledPlan)
}));
}

[RequireServerFact("4.0.0", GreaterThanOrEqualTo)]
[RequireServerFact("4.0.0", GreaterThanOrEqualTo, Skip = "Broken with servers 5.6+")]
public void ShouldReturnPlanButNoProfile()
{
VerifySummary(
Expand Down Expand Up @@ -252,7 +252,7 @@ public void ShouldNotReturnNotifications()
Matches<IResultSummary>(s => s.Notifications.Should().BeNull()));
}

[RequireServerFact("4.0.0", GreaterThanOrEqualTo)]
[RequireServerFact("4.0.0", "5.6.0", Between)]
public void ShouldReturnNotifications()
{
VerifySummary(
Expand All @@ -268,7 +268,35 @@ public void ShouldReturnNotifications()
null,
null,
null,
"WARNING")
"WARNING",
null)
}
},
options => options.ExcludingMissingMembers()
.Excluding(x => x.SelectedMemberPath == "Notifications[0].Position")
.Excluding(x => x.SelectedMemberPath == "Notifications[0].Title")
.Excluding(x => x.SelectedMemberPath == "Notifications[0].Description")));
}


[RequireServerFact("5.7.0", GreaterThanOrEqualTo)]
public void ShouldReturnNotificationsWithCategory()
{
VerifySummary(
"EXPLAIN MATCH (n:ThisLabelDoesNotExistReactive) RETURN n",
null,
MatchesSummary(
new
{
Notifications = new[]
{
new Notification(
"Neo.ClientNotification.Statement.UnknownLabelWarning",
null,
null,
null,
"WARNING",
"UNRECOGNIZED")
}
},
options => options.ExcludingMissingMembers()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,27 @@ List<string> GetPaths()
configBuilder.WithFetchSize(data.fetchSize.Value);
}

var logger = new SimpleLogger();
if (data.notificationsMinSeverity != null || data.notificationsDisabledCategories != null)
{
if (data.notificationsMinSeverity == TestkitConstants.NotificationsConfig.Disabled)
{
configBuilder.WithNotificationsDisabled();
}
else
{
var sev = Enum.TryParse<Severity>(data.notificationsMinSeverity ?? string.Empty, true, out var severity)
? (Severity?)severity
: null;

var cats = data.notificationsDisabledCategories
?.Select(x => Enum.Parse<Category>(x, true))
.ToArray();

configBuilder.WithNotifications(sev, cats);
}
}

var logger = new SimpleLogger();
configBuilder.WithLogger(logger);
}

Expand Down Expand Up @@ -177,5 +196,8 @@ public string[] trustedCertificates
}

public bool? encrypted { get; set; }

public string notificationsMinSeverity { get; set; }
public string[] notificationsDisabledCategories { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public override NewDriver.NewDriverType ReadJson(
newDriverRequest.connectionAcquisitionTimeoutMs = jsonObj["connectionAcquisitionTimeoutMs"]?.Value<int?>();
newDriverRequest.fetchSize = jsonObj["fetchSize"]?.Value<long?>();
newDriverRequest.maxTxRetryTimeMs = jsonObj["maxTxRetryTimeMs"]?.Value<long?>();
newDriverRequest.notificationsMinSeverity = jsonObj["notificationsMinSeverity"]?.Value<string>();

if (jsonObj.TryGetValue("trustedCertificates", out var token))
{
Expand All @@ -59,6 +60,9 @@ public override NewDriver.NewDriverType ReadJson(
newDriverRequest.encrypted = token.Value<bool?>();
}

if (jsonObj.TryGetValue("notificationsDisabledCategories", out token))
newDriverRequest.notificationsDisabledCategories = token.ToObject<string[]>();

return newDriverRequest;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ private static object CreateNotificationList(IResultSummary summary)
return summary.Notifications.Select(
x => new
{
rawCategory = x.RawCategory ?? String.Empty,
category = x.Category.ToString().ToUpper(),
severity = x.Severity,
rawSeverityLevel = x.RawSeverityLevel ?? String.Empty,
severityLevel = x.SeverityLevel.ToString().ToUpper(),
description = x.Description,
code = x.Code,
title = x.Title
Expand All @@ -184,7 +188,11 @@ private static object CreateNotificationList(IResultSummary summary)
return summary.Notifications.Select(
x => new
{
rawCategory = x.RawCategory ?? String.Empty,
category = x.Category.ToString().ToUpper(),
severity = x.Severity,
rawSeverityLevel = x.RawSeverityLevel ?? String.Empty,
severityLevel = x.SeverityLevel.ToString().ToUpper(),
description = x.Description,
code = x.Code,
title = x.Title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;

Expand Down Expand Up @@ -85,6 +87,26 @@ private void SessionConfig(SessionConfigBuilder configBuilder)
ObjManager.GetObject<NewBookmarkManager>(data.bookmarkManagerId)
.BookmarkManager);
}

if (data.notificationsMinSeverity != null || data.notificationsDisabledCategories != null)
{
if (data.notificationsMinSeverity == TestkitConstants.NotificationsConfig.Disabled)
{
configBuilder.WithNotificationsDisabled();
}
else
{
var sev = Enum.TryParse<Severity>(data.notificationsMinSeverity ?? string.Empty, true, out var severity)
? (Severity?)severity
: null;

var cats = data.notificationsDisabledCategories
?.Select(x => Enum.Parse<Category>(x, true))
.ToArray();

configBuilder.WithNotifications(sev, cats);
}
}
}

public override async Task Process()
Expand Down Expand Up @@ -127,5 +149,10 @@ public class NewSessionType
public string impersonatedUser { get; set; }

public string bookmarkManagerId { get; set; }

public AuthorizationToken authorizationToken { get; set; }

public string notificationsMinSeverity { get; set; }
public string[] notificationsDisabledCategories { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) "Neo4j"
// Neo4j Sweden AB [http://neo4j.com]
//
// This file is part of Neo4j.
//
// Licensed 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.

namespace Neo4j.Driver.Tests.TestBackend;

public class TestkitConstants
{
public static class NotificationsConfig
{
public const string Disabled = "OFF";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ static SupportedFeatures()
"Feature:API:Driver.ExecuteQuery",
"Feature:API:Driver:GetServerInfo",
"Feature:API:Driver.IsEncrypted",
"Feature:API:Driver:NotificationsConfig",
"Feature:API:Driver.VerifyConnectivity",
//"Feature:API:Liveness.Check",
"Feature:API:Result.List",
"Feature:API:Result.Peek",
"Feature:API:Result.Single",
"Feature:API:Session:NotificationsConfig",
"Feature:API:SSLConfig",
"Feature:API:SSLSchemes",
"Feature:API:Type.Temporal",
Expand All @@ -51,6 +53,7 @@ static SupportedFeatures()
"Feature:Bolt:4.3",
"Feature:Bolt:4.4",
"Feature:Bolt:5.0",
"Feature:Bolt:5.2",
"Feature:Bolt:Patch:UTC",
"Feature:Impersonation",
//"Feature:TLS:1.1",
Expand Down
12 changes: 8 additions & 4 deletions Neo4j.Driver/Neo4j.Driver.Tests/AsyncSessionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public async Task ShouldDelegateToProtocolRunAutoCommitTxAsync(bool reactive)
await session.RunAsync("lalalal");

mockConn.Verify(
x => x.RunInAutoCommitTransactionAsync(It.IsAny<AutoCommitParams>()),
x => x.RunInAutoCommitTransactionAsync(It.IsAny<AutoCommitParams>(),
It.IsAny<INotificationsConfig>()),
Times.Once);
}
}
Expand Down Expand Up @@ -207,7 +208,8 @@ public async void ShouldCloseConnectionOnRunIfBeginTxFailed()
It.IsAny<string>(),
It.IsAny<Bookmarks>(),
It.IsAny<TransactionConfig>(),
It.IsAny<string>()))
It.IsAny<string>(),
It.IsAny<INotificationsConfig>()))
.Throws(new IOException("Triggered an error when beginTx"));

var session = NewSession(mockConn.Object);
Expand Down Expand Up @@ -235,7 +237,8 @@ public async void ShouldCloseConnectionOnNewBeginTxIfBeginTxFailed()
It.IsAny<string>(),
It.IsAny<Bookmarks>(),
It.IsAny<TransactionConfig>(),
It.IsAny<string>()))
It.IsAny<string>(),
It.IsAny<INotificationsConfig>()))
.Returns(Task.CompletedTask)
.Callback(
() =>
Expand Down Expand Up @@ -274,7 +277,8 @@ public async void ShouldCloseConnectionIfBeginTxFailed()
It.IsAny<string>(),
It.IsAny<Bookmarks>(),
It.IsAny<TransactionConfig>(),
It.IsAny<string>()))
It.IsAny<string>(),
It.IsAny<INotificationsConfig>()))
.Throws(new IOException("Triggered an error when beginTx"));

var session = NewSession(mockConn.Object);
Expand Down
9 changes: 7 additions & 2 deletions Neo4j.Driver/Neo4j.Driver.Tests/ConnectionPoolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ public async Task ShouldCallConnInit()
await connectionPool.AcquireAsync(AccessMode.Read, null, null, Bookmarks.Empty);

//Then
mock.Verify(x => x.InitAsync(It.IsAny<CancellationToken>()), Times.Once);
mock.Verify(
x => x.InitAsync(It.IsAny<INotificationsConfig>(), It.IsAny<CancellationToken>()),
Times.Once);
}

[Fact]
Expand Down Expand Up @@ -217,7 +219,10 @@ public async Task ShouldCreateNewWhenQueueIsEmpty()
public async Task ShouldCloseConnectionIfFailedToCreate()
{
var connMock = new Mock<IPooledConnection>();
connMock.Setup(x => x.InitAsync(It.IsAny<CancellationToken>())).Throws<NotImplementedException>();
connMock.Setup(x => x.InitAsync(
It.IsAny<INotificationsConfig>(),
It.IsAny<CancellationToken>()))
.Throws<NotImplementedException>();

var connFactory = new MockedConnectionFactory(connMock.Object);
var pool = new ConnectionPool(connFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,17 @@ public async Task ShouldConnectClient()
var conn = NewSocketConnection(mockClient.Object, boltProtocolFactory: bpFactory.Object);

// When
await conn.InitAsync();
await conn.InitAsync(null);

// Then
mockClient.Verify(c => c.ConnectAsync(null, CancellationToken.None), Times.Once);
protocolMock.Verify(x => x.LoginAsync(conn, It.IsAny<string>(), It.IsAny<IAuthToken>()), Times.Once);
protocolMock.Verify(
x => x.AuthenticateAsync(
conn,
It.IsAny<string>(),
It.IsAny<IAuthToken>(),
It.IsAny<INotificationsConfig>()),
Times.Once);
}

[Fact]
Expand All @@ -94,7 +100,7 @@ public async Task ShouldThrowClientErrorIfFailedToConnectToServerWithinTimeout()
// ReSharper disable once ObjectCreationAsStatement
var conn = new SocketConnection(mockClient.Object, AuthToken, UserAgent, Logger, Server);
// When
var error = await Record.ExceptionAsync(() => conn.InitAsync());
var error = await Record.ExceptionAsync(() => conn.InitAsync(null));
// Then
error.Should().BeOfType<IOException>();
error.Message.Should().Be("I will stop socket conn from initialization");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public void ShouldThrowWhenNotCommitMessage()
[InlineData(4, 3)]
[InlineData(4, 4)]
[InlineData(5, 0)]
[InlineData(5, 2)]
[InlineData(6, 0)]
public void ShouldSerialize(int major, int minor)
{
Expand All @@ -62,8 +63,8 @@ public void ShouldSerialize(int major, int minor)
"neo4j",
new InternalBookmarks("a"),
null,
null,
AccessMode.Read,
null,
null);

BeginMessageSerializer.Instance.Serialize(psw, message);
Expand Down
Loading

0 comments on commit df22aeb

Please sign in to comment.