Skip to content

Commit 4d6fd03

Browse files
committed
Introduce notification configuration, severity and category
Improve and expand the existing notification API. A new `NotificationSeverity` type represents a notification severity level. It includes 2 public constants: - `INFORMATION` - `WARNING` A new `NotificationCategory` type represents a notification category. It includes 6 public constants: - `HINT` - `UNRECOGNIZED` - `UNSUPPORTED` - `PERFORMANCE` - `DEPRECATION` - `GENERIC` The `Notification` class has been extended with the following 4 methods: - `Optional<NotificationSeverity> severityLevel()` - `Optional<String> rawSeverityLevel()` - `Optional<NotificationCategory> category()` - `Optional<String> rawCategory()` The `raw` methods return a `String` representation returned by the server. In case of an unrecognised value, both `severityLevel()` and `category()` methods return an empty `Optional`. This may happen if a new value is introduced in a future server version and a previous driver version does not support it. Additionally, an empty `Optional` may be returned when driver communicates with a server version that does not supply these values. The `severity()` method has been deprecated in favour of the `rawSeverityLevel()` method. A new `NotificationConfig` type has been introduced to allow notification preferences management. By default, the server determines what notifications are provided to the driver. However, user can set a minimum severity level and/or a set of disabled notification categories to manage its expectations. This feature is only supported on Bolt protocol version 5.2 and above. Both the `Config` and the `SessionConfig` support this new configuration. Sample usage: ```java // sets minimum notification severity level to WARNING // and explicitly disables both GENERIC and HINT notification categories var driverConfig = Config.builder() .withNotificationConfig(NotificationConfig.enableMinimumSeverityAndDisableCategories(NotificationSeverity.WARNING, Set.of(NotificationCategory.GENERIC, NotificationCategory.HINT))) .build(); // disables all notifications var sessionConfig = SessionConfig.builder() .withNotificationConfig(NotificationConfig.disableAll()) .build(); ``` This update includes support for both 5.1 and 5.2 versions. The latter is required for the full support of the new notification updates.
1 parent e2962b8 commit 4d6fd03

File tree

79 files changed

+2328
-266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2328
-266
lines changed

driver/clirr-ignored-differences.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,4 +433,28 @@
433433
<method>org.neo4j.driver.BookmarkManager queryTaskBookmarkManager()</method>
434434
</difference>
435435

436+
<difference>
437+
<className>org/neo4j/driver/summary/Notification</className>
438+
<differenceType>7012</differenceType>
439+
<method>java.util.Optional severityLevel()</method>
440+
</difference>
441+
442+
<difference>
443+
<className>org/neo4j/driver/summary/Notification</className>
444+
<differenceType>7012</differenceType>
445+
<method>java.util.Optional rawSeverityLevel()</method>
446+
</difference>
447+
448+
<difference>
449+
<className>org/neo4j/driver/summary/Notification</className>
450+
<differenceType>7012</differenceType>
451+
<method>java.util.Optional category()</method>
452+
</difference>
453+
454+
<difference>
455+
<className>org/neo4j/driver/summary/Notification</className>
456+
<differenceType>7012</differenceType>
457+
<method>java.util.Optional rawCategory()</method>
458+
</difference>
459+
436460
</differences>

driver/src/main/java/org/neo4j/driver/Config.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ public final class Config implements Serializable {
143143
* The user_agent configured for this driver.
144144
*/
145145
private final String userAgent;
146+
/**
147+
* The notification config.
148+
*/
149+
private final NotificationConfig notificationConfig;
146150
/**
147151
* The {@link MetricsAdapter}.
148152
*/
@@ -166,6 +170,7 @@ private Config(ConfigBuilder builder) {
166170
this.maxTransactionRetryTimeMillis = builder.maxTransactionRetryTimeMillis;
167171
this.resolver = builder.resolver;
168172
this.fetchSize = builder.fetchSize;
173+
this.notificationConfig = builder.notificationConfig;
169174

170175
this.eventLoopThreads = builder.eventLoopThreads;
171176
this.metricsAdapter = builder.metricsAdapter;
@@ -311,6 +316,15 @@ public long fetchSize() {
311316
return fetchSize;
312317
}
313318

319+
/**
320+
* Returns notification config.
321+
* @return the notification config
322+
* @since 5.7
323+
*/
324+
public NotificationConfig notificationConfig() {
325+
return notificationConfig;
326+
}
327+
314328
/**
315329
* Returns the number of {@link io.netty.channel.EventLoop} threads.
316330
* @return the number of threads
@@ -363,6 +377,7 @@ public static final class ConfigBuilder {
363377
private MetricsAdapter metricsAdapter = MetricsAdapter.DEV_NULL;
364378
private long fetchSize = FetchSizeUtil.DEFAULT_FETCH_SIZE;
365379
private int eventLoopThreads = 0;
380+
private NotificationConfig notificationConfig = NotificationConfig.defaultConfig();
366381

367382
private ConfigBuilder() {}
368383

@@ -757,6 +772,19 @@ public ConfigBuilder withUserAgent(String userAgent) {
757772
return this;
758773
}
759774

775+
/**
776+
* Sets notification config.
777+
* <p>
778+
* This configuration is supported over Bolt protocol version 5.2 and above.
779+
* @param notificationConfig the notification config
780+
* @return this builder
781+
* @since 5.7
782+
*/
783+
public ConfigBuilder withNotificationConfig(NotificationConfig notificationConfig) {
784+
this.notificationConfig = Objects.requireNonNull(notificationConfig, "notificationConfig must not be null");
785+
return this;
786+
}
787+
760788
/**
761789
* Extracts the driver version from the driver jar MANIFEST.MF file.
762790
*/
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import java.io.Serializable;
22+
import org.neo4j.driver.internal.InternalNotificationCategory;
23+
import org.neo4j.driver.internal.InternalNotificationCategory.Type;
24+
25+
/**
26+
* Notification category.
27+
*
28+
* @since 5.7
29+
*/
30+
public sealed interface NotificationCategory extends Serializable permits InternalNotificationCategory {
31+
/**
32+
* A hint category.
33+
* <p>
34+
* For instance, the given hint cannot be satisfied.
35+
*/
36+
NotificationCategory HINT = new InternalNotificationCategory(Type.HINT);
37+
38+
/**
39+
* An unrecognized category.
40+
* <p>
41+
* For instance, the query or command mentions entities that are unknown to the system.
42+
*/
43+
NotificationCategory UNRECOGNIZED = new InternalNotificationCategory(Type.UNRECOGNIZED);
44+
45+
/**
46+
* An unsupported category.
47+
* <p>
48+
* For instance, the query/command is trying to use features that are not supported by the current system or using
49+
* features that are experimental and should not be used in production.
50+
*/
51+
NotificationCategory UNSUPPORTED = new InternalNotificationCategory(Type.UNSUPPORTED);
52+
53+
/**
54+
* A performance category.
55+
* <p>
56+
* For instance, the query uses costly operations and might be slow.
57+
*/
58+
NotificationCategory PERFORMANCE = new InternalNotificationCategory(Type.PERFORMANCE);
59+
60+
/**
61+
* A deprecation category.
62+
* <p>
63+
* For instance, the query/command use deprecated features that should be replaced.
64+
*/
65+
NotificationCategory DEPRECATION = new InternalNotificationCategory(Type.DEPRECATION);
66+
67+
/**
68+
* A generic category.
69+
* <p>
70+
* For instance, notifications that are not part of a more specific class.
71+
*/
72+
NotificationCategory GENERIC = new InternalNotificationCategory(Type.GENERIC);
73+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import java.io.Serializable;
22+
import java.util.Objects;
23+
import java.util.Set;
24+
import org.neo4j.driver.internal.InternalNotificationConfig;
25+
import org.neo4j.driver.internal.InternalNotificationSeverity;
26+
27+
/**
28+
* Notification configuration that defines what notifications the server should supply to the driver.
29+
* <p>
30+
* This configuration is only supported over Bolt protocol version 5.2 and above. It is effectively ignored on the previous versions.
31+
* @since 5.7
32+
*/
33+
public sealed interface NotificationConfig extends Serializable permits InternalNotificationConfig {
34+
/**
35+
* Returns a default notification config.
36+
* <p>
37+
* It has no options activated, meaning the resulting behaviour depends on an upstream entity. For instance,
38+
* when this config is set on the session level, the resulting behaviour depends on the driver's config.
39+
* Likewise, when this config is set on the driver level, the resulting behaviour depends on the server.
40+
* @return the default config
41+
*/
42+
static NotificationConfig defaultConfig() {
43+
return new InternalNotificationConfig(null, null);
44+
}
45+
46+
/**
47+
* A config that disables all notifications.
48+
* @return the config that disables all notifications
49+
*/
50+
static NotificationConfig disableAll() {
51+
return new InternalNotificationConfig(InternalNotificationSeverity.OFF, null);
52+
}
53+
54+
/**
55+
* Returns a config that sets a minimum severity level for notifications.
56+
*
57+
* @param minimumSeverity the minimum severity level
58+
* @return the config
59+
*/
60+
static NotificationConfig enableMinimumSeverity(NotificationSeverity minimumSeverity) {
61+
Objects.requireNonNull(minimumSeverity, "minimumSeverity must not be null");
62+
return new InternalNotificationConfig(minimumSeverity, null);
63+
}
64+
65+
/**
66+
* Returns a config that disables a set of notification categories.
67+
*
68+
* @param disabledCategories the categories to disable, an empty set means no categories are disabled
69+
* @return the config
70+
*/
71+
static NotificationConfig disableCategories(Set<NotificationCategory> disabledCategories) {
72+
Objects.requireNonNull(disabledCategories, "disabledCategories must not be null");
73+
return new InternalNotificationConfig(null, Set.copyOf(disabledCategories));
74+
}
75+
76+
/**
77+
* Returns a config that sets a minimum severity level for notifications and also disables a set of notification categories.
78+
*
79+
* @param minimumSeverity the minimum severity level
80+
* @param disabledCategories the categories to disable, an empty set means no categories are disabled
81+
* @return the config
82+
*/
83+
static NotificationConfig enableMinimumSeverityAndDisableCategories(
84+
NotificationSeverity minimumSeverity, Set<NotificationCategory> disabledCategories) {
85+
Objects.requireNonNull(minimumSeverity, "minimumSeverity must not be null");
86+
Objects.requireNonNull(disabledCategories, "disabledCategories must not be null");
87+
return new InternalNotificationConfig(minimumSeverity, Set.copyOf(disabledCategories));
88+
}
89+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import static org.neo4j.driver.internal.InternalNotificationSeverity.Type;
22+
23+
import java.io.Serializable;
24+
import org.neo4j.driver.internal.InternalNotificationSeverity;
25+
26+
/**
27+
* Notification severity level.
28+
*
29+
* @since 5.7
30+
*/
31+
public sealed interface NotificationSeverity extends Serializable, Comparable<NotificationSeverity>
32+
permits InternalNotificationSeverity {
33+
/**
34+
* An information severity level.
35+
*/
36+
NotificationSeverity INFORMATION = new InternalNotificationSeverity(Type.INFORMATION, 800);
37+
/**
38+
* A warning severity level.
39+
*/
40+
NotificationSeverity WARNING = new InternalNotificationSeverity(Type.WARNING, 900);
41+
}

driver/src/main/java/org/neo4j/driver/SessionConfig.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public final class SessionConfig implements Serializable {
6565
* The bookmark manager.
6666
*/
6767
private final BookmarkManager bookmarkManager;
68+
/**
69+
* The notification config.
70+
*/
71+
private final NotificationConfig notificationConfig;
6872

6973
private SessionConfig(Builder builder) {
7074
this.bookmarks = builder.bookmarks;
@@ -73,6 +77,7 @@ private SessionConfig(Builder builder) {
7377
this.fetchSize = builder.fetchSize;
7478
this.impersonatedUser = builder.impersonatedUser;
7579
this.bookmarkManager = builder.bookmarkManager;
80+
this.notificationConfig = builder.notificationConfig;
7681
}
7782

7883
/**
@@ -161,6 +166,15 @@ public Optional<BookmarkManager> bookmarkManager() {
161166
return Optional.ofNullable(bookmarkManager);
162167
}
163168

169+
/**
170+
* Returns notification config.
171+
* @return the notification config
172+
* @since 5.7
173+
*/
174+
public NotificationConfig notificationConfig() {
175+
return notificationConfig;
176+
}
177+
164178
@Override
165179
public boolean equals(Object o) {
166180
if (this == o) {
@@ -175,7 +189,8 @@ public boolean equals(Object o) {
175189
&& Objects.equals(database, that.database)
176190
&& Objects.equals(fetchSize, that.fetchSize)
177191
&& Objects.equals(impersonatedUser, that.impersonatedUser)
178-
&& Objects.equals(bookmarkManager, that.bookmarkManager);
192+
&& Objects.equals(bookmarkManager, that.bookmarkManager)
193+
&& Objects.equals(notificationConfig, that.notificationConfig);
179194
}
180195

181196
@Override
@@ -203,6 +218,7 @@ public static final class Builder {
203218
private String database = null;
204219
private String impersonatedUser = null;
205220
private BookmarkManager bookmarkManager;
221+
private NotificationConfig notificationConfig = NotificationConfig.defaultConfig();
206222

207223
private Builder() {}
208224

@@ -366,6 +382,19 @@ public Builder withBookmarkManager(BookmarkManager bookmarkManager) {
366382
return this;
367383
}
368384

385+
/**
386+
* Sets notification config.
387+
* <p>
388+
* This configuration is supported over Bolt protocol version 5.2 and above.
389+
* @param notificationConfig the notification config
390+
* @return this builder
391+
* @since 5.7
392+
*/
393+
public Builder withNotificationConfig(NotificationConfig notificationConfig) {
394+
this.notificationConfig = Objects.requireNonNull(notificationConfig, "notificationConfig must not be null");
395+
return this;
396+
}
397+
369398
/**
370399
* Builds the {@link SessionConfig}.
371400
* @return the config

driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,13 @@ protected ChannelConnector createConnector(
179179
Clock clock,
180180
RoutingContext routingContext) {
181181
return new ChannelConnectorImpl(
182-
settings, securityPlan, config.logging(), clock, routingContext, getDomainNameResolver());
182+
settings,
183+
securityPlan,
184+
config.logging(),
185+
clock,
186+
routingContext,
187+
getDomainNameResolver(),
188+
config.notificationConfig());
183189
}
184190

185191
private InternalDriver createDriver(

0 commit comments

Comments
 (0)