diff --git a/driver/clirr-ignored-differences.xml b/driver/clirr-ignored-differences.xml
index 59b51ea0af..5ae3f844b2 100644
--- a/driver/clirr-ignored-differences.xml
+++ b/driver/clirr-ignored-differences.xml
@@ -433,4 +433,28 @@
org.neo4j.driver.BookmarkManager queryTaskBookmarkManager()
+
+ org/neo4j/driver/summary/Notification
+ 7012
+ java.util.Optional severityLevel()
+
+
+
+ org/neo4j/driver/summary/Notification
+ 7012
+ java.util.Optional rawSeverityLevel()
+
+
+
+ org/neo4j/driver/summary/Notification
+ 7012
+ java.util.Optional category()
+
+
+
+ org/neo4j/driver/summary/Notification
+ 7012
+ java.util.Optional rawCategory()
+
+
diff --git a/driver/src/main/java/org/neo4j/driver/Config.java b/driver/src/main/java/org/neo4j/driver/Config.java
index 11255f7822..7afdadad09 100644
--- a/driver/src/main/java/org/neo4j/driver/Config.java
+++ b/driver/src/main/java/org/neo4j/driver/Config.java
@@ -32,6 +32,7 @@
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
+import org.neo4j.driver.exceptions.UnsupportedFeatureException;
import org.neo4j.driver.internal.SecuritySettings;
import org.neo4j.driver.internal.async.pool.PoolSettings;
import org.neo4j.driver.internal.cluster.RoutingSettings;
@@ -143,6 +144,10 @@ public final class Config implements Serializable {
* The user_agent configured for this driver.
*/
private final String userAgent;
+ /**
+ * The notification config.
+ */
+ private final NotificationConfig notificationConfig;
/**
* The {@link MetricsAdapter}.
*/
@@ -166,6 +171,7 @@ private Config(ConfigBuilder builder) {
this.maxTransactionRetryTimeMillis = builder.maxTransactionRetryTimeMillis;
this.resolver = builder.resolver;
this.fetchSize = builder.fetchSize;
+ this.notificationConfig = builder.notificationConfig;
this.eventLoopThreads = builder.eventLoopThreads;
this.metricsAdapter = builder.metricsAdapter;
@@ -311,6 +317,15 @@ public long fetchSize() {
return fetchSize;
}
+ /**
+ * Returns notification config.
+ * @return the notification config
+ * @since 5.7
+ */
+ public NotificationConfig notificationConfig() {
+ return notificationConfig;
+ }
+
/**
* Returns the number of {@link io.netty.channel.EventLoop} threads.
* @return the number of threads
@@ -363,6 +378,7 @@ public static final class ConfigBuilder {
private MetricsAdapter metricsAdapter = MetricsAdapter.DEV_NULL;
private long fetchSize = FetchSizeUtil.DEFAULT_FETCH_SIZE;
private int eventLoopThreads = 0;
+ private NotificationConfig notificationConfig = NotificationConfig.defaultConfig();
private ConfigBuilder() {}
@@ -757,6 +773,22 @@ public ConfigBuilder withUserAgent(String userAgent) {
return this;
}
+ /**
+ * Sets notification config.
+ *
+ * Any configuration other than the {@link NotificationConfig#defaultConfig()} requires a minimum Bolt protocol
+ * version 5.2. Otherwise, an {@link UnsupportedFeatureException} will be emitted when the driver comes across a
+ * Bolt connection that does not support this feature. For instance, when running a query.
+ *
+ * @param notificationConfig the notification config
+ * @return this builder
+ * @since 5.7
+ */
+ public ConfigBuilder withNotificationConfig(NotificationConfig notificationConfig) {
+ this.notificationConfig = Objects.requireNonNull(notificationConfig, "notificationConfig must not be null");
+ return this;
+ }
+
/**
* Extracts the driver version from the driver jar MANIFEST.MF file.
*/
diff --git a/driver/src/main/java/org/neo4j/driver/NotificationCategory.java b/driver/src/main/java/org/neo4j/driver/NotificationCategory.java
new file mode 100644
index 0000000000..6c33736366
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/NotificationCategory.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver;
+
+import java.io.Serializable;
+import org.neo4j.driver.internal.InternalNotificationCategory;
+import org.neo4j.driver.internal.InternalNotificationCategory.Type;
+
+/**
+ * Notification category.
+ *
+ * @since 5.7
+ */
+public sealed interface NotificationCategory extends Serializable permits InternalNotificationCategory {
+ /**
+ * A hint category.
+ *
+ * For instance, the given hint cannot be satisfied.
+ */
+ NotificationCategory HINT = new InternalNotificationCategory(Type.HINT);
+
+ /**
+ * An unrecognized category.
+ *
+ * For instance, the query or command mentions entities that are unknown to the system.
+ */
+ NotificationCategory UNRECOGNIZED = new InternalNotificationCategory(Type.UNRECOGNIZED);
+
+ /**
+ * An unsupported category.
+ *
+ * For instance, the query/command is trying to use features that are not supported by the current system or using
+ * features that are experimental and should not be used in production.
+ */
+ NotificationCategory UNSUPPORTED = new InternalNotificationCategory(Type.UNSUPPORTED);
+
+ /**
+ * A performance category.
+ *
+ * For instance, the query uses costly operations and might be slow.
+ */
+ NotificationCategory PERFORMANCE = new InternalNotificationCategory(Type.PERFORMANCE);
+
+ /**
+ * A deprecation category.
+ *
+ * For instance, the query/command use deprecated features that should be replaced.
+ */
+ NotificationCategory DEPRECATION = new InternalNotificationCategory(Type.DEPRECATION);
+
+ /**
+ * A generic category.
+ *
+ * For instance, notifications that are not part of a more specific class.
+ */
+ NotificationCategory GENERIC = new InternalNotificationCategory(Type.GENERIC);
+}
diff --git a/driver/src/main/java/org/neo4j/driver/NotificationConfig.java b/driver/src/main/java/org/neo4j/driver/NotificationConfig.java
new file mode 100644
index 0000000000..655474fcdd
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/NotificationConfig.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver;
+
+import java.io.Serializable;
+import java.util.Set;
+import org.neo4j.driver.internal.InternalNotificationConfig;
+import org.neo4j.driver.internal.InternalNotificationSeverity;
+import org.neo4j.driver.summary.ResultSummary;
+
+/**
+ * A notification configuration defining what notifications should be supplied by the server.
+ *
+ * There are currently 2 optional settings that may be activated:
+ *
+ * - Minimum notification severity - sets a baseline severity for notifications, similar to the logging levels.
+ * - A set of disabled notification categories - explicitly disables a set of notification categories.
+ *
+ *
+ * By default, both options are not activated.
+ *
+ * @since 5.7
+ * @see ResultSummary#notifications()
+ * @see org.neo4j.driver.summary.Notification
+ */
+public sealed interface NotificationConfig extends Serializable permits InternalNotificationConfig {
+ /**
+ * Returns a default notification configuration.
+ *
+ * The default configuration has no settings activated, meaning the resulting behaviour depends on an upstream
+ * context. For instance, when this config is set on the session level, the resulting behaviour depends on the
+ * driver's config. Likewise, when this config is set on the driver level, the resulting behaviour depends on the
+ * server.
+ *
+ * @return the default config
+ */
+ static NotificationConfig defaultConfig() {
+ return new InternalNotificationConfig(null, null);
+ }
+
+ /**
+ * A config that disables all notifications.
+ *
+ * @return the config that disables all notifications
+ */
+ static NotificationConfig disableAllConfig() {
+ return new InternalNotificationConfig(InternalNotificationSeverity.OFF, null);
+ }
+
+ /**
+ * Returns a config that sets a minimum severity level for notifications.
+ *
+ * @param minimumSeverity the minimum severity level
+ * @return the config
+ */
+ NotificationConfig enableMinimumSeverity(NotificationSeverity minimumSeverity);
+
+ /**
+ * Returns a config that disables a set of notification categories.
+ *
+ * @param disabledCategories the categories to disable, an empty set means no categories are disabled
+ * @return the config
+ */
+ NotificationConfig disableCategories(Set disabledCategories);
+}
diff --git a/driver/src/main/java/org/neo4j/driver/NotificationSeverity.java b/driver/src/main/java/org/neo4j/driver/NotificationSeverity.java
new file mode 100644
index 0000000000..e911a18eda
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/NotificationSeverity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver;
+
+import static org.neo4j.driver.internal.InternalNotificationSeverity.Type;
+
+import java.io.Serializable;
+import org.neo4j.driver.internal.InternalNotificationSeverity;
+
+/**
+ * Notification severity level.
+ *
+ * @since 5.7
+ */
+public sealed interface NotificationSeverity extends Serializable, Comparable
+ permits InternalNotificationSeverity {
+ /**
+ * An information severity level.
+ */
+ NotificationSeverity INFORMATION = new InternalNotificationSeverity(Type.INFORMATION, 800);
+ /**
+ * A warning severity level.
+ */
+ NotificationSeverity WARNING = new InternalNotificationSeverity(Type.WARNING, 900);
+}
diff --git a/driver/src/main/java/org/neo4j/driver/SessionConfig.java b/driver/src/main/java/org/neo4j/driver/SessionConfig.java
index abcca9f363..aad02a68a4 100644
--- a/driver/src/main/java/org/neo4j/driver/SessionConfig.java
+++ b/driver/src/main/java/org/neo4j/driver/SessionConfig.java
@@ -27,6 +27,7 @@
import java.util.Objects;
import java.util.Optional;
import org.neo4j.driver.async.AsyncSession;
+import org.neo4j.driver.exceptions.UnsupportedFeatureException;
import org.neo4j.driver.reactive.ReactiveSession;
import org.neo4j.driver.reactive.RxSession;
import org.neo4j.driver.util.Experimental;
@@ -65,6 +66,10 @@ public final class SessionConfig implements Serializable {
* The bookmark manager.
*/
private final BookmarkManager bookmarkManager;
+ /**
+ * The notification config.
+ */
+ private final NotificationConfig notificationConfig;
private SessionConfig(Builder builder) {
this.bookmarks = builder.bookmarks;
@@ -73,6 +78,7 @@ private SessionConfig(Builder builder) {
this.fetchSize = builder.fetchSize;
this.impersonatedUser = builder.impersonatedUser;
this.bookmarkManager = builder.bookmarkManager;
+ this.notificationConfig = builder.notificationConfig;
}
/**
@@ -161,6 +167,15 @@ public Optional bookmarkManager() {
return Optional.ofNullable(bookmarkManager);
}
+ /**
+ * Returns notification config.
+ * @return the notification config
+ * @since 5.7
+ */
+ public NotificationConfig notificationConfig() {
+ return notificationConfig;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -175,7 +190,8 @@ public boolean equals(Object o) {
&& Objects.equals(database, that.database)
&& Objects.equals(fetchSize, that.fetchSize)
&& Objects.equals(impersonatedUser, that.impersonatedUser)
- && Objects.equals(bookmarkManager, that.bookmarkManager);
+ && Objects.equals(bookmarkManager, that.bookmarkManager)
+ && Objects.equals(notificationConfig, that.notificationConfig);
}
@Override
@@ -203,6 +219,7 @@ public static final class Builder {
private String database = null;
private String impersonatedUser = null;
private BookmarkManager bookmarkManager;
+ private NotificationConfig notificationConfig = NotificationConfig.defaultConfig();
private Builder() {}
@@ -366,6 +383,22 @@ public Builder withBookmarkManager(BookmarkManager bookmarkManager) {
return this;
}
+ /**
+ * Sets notification config.
+ *
+ * Any configuration other than the {@link NotificationConfig#defaultConfig()} requires a minimum Bolt protocol
+ * version 5.2. Otherwise, an {@link UnsupportedFeatureException} will be emitted when the driver comes across a
+ * Bolt connection that does not support this feature. For instance, when running a query.
+ *
+ * @param notificationConfig the notification config
+ * @return this builder
+ * @since 5.7
+ */
+ public Builder withNotificationConfig(NotificationConfig notificationConfig) {
+ this.notificationConfig = Objects.requireNonNull(notificationConfig, "notificationConfig must not be null");
+ return this;
+ }
+
/**
* Builds the {@link SessionConfig}.
* @return the config
diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/UnsupportedFeatureException.java b/driver/src/main/java/org/neo4j/driver/exceptions/UnsupportedFeatureException.java
new file mode 100644
index 0000000000..45c4d945ad
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/exceptions/UnsupportedFeatureException.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.exceptions;
+
+import java.io.Serial;
+
+/**
+ * A feature is not supported in a given setup.
+ * @since 5.7
+ */
+public class UnsupportedFeatureException extends ClientException {
+ @Serial
+ private static final long serialVersionUID = 1161333003602398544L;
+
+ /**
+ * Constructs a new instance.
+ * @param message the message
+ */
+ public UnsupportedFeatureException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new instance.
+ * @param message the message
+ * @param cause the cause
+ */
+ public UnsupportedFeatureException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java
index 1aa87743bd..8a9056311f 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java
@@ -179,7 +179,13 @@ protected ChannelConnector createConnector(
Clock clock,
RoutingContext routingContext) {
return new ChannelConnectorImpl(
- settings, securityPlan, config.logging(), clock, routingContext, getDomainNameResolver());
+ settings,
+ securityPlan,
+ config.logging(),
+ clock,
+ routingContext,
+ getDomainNameResolver(),
+ config.notificationConfig());
}
private InternalDriver createDriver(
diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationCategory.java b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationCategory.java
new file mode 100644
index 0000000000..e63c509d68
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationCategory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Optional;
+import org.neo4j.driver.NotificationCategory;
+
+public record InternalNotificationCategory(Type type) implements NotificationCategory {
+
+ public InternalNotificationCategory {
+ Objects.requireNonNull(type, "type must not be null");
+ }
+
+ public enum Type {
+ HINT,
+ UNRECOGNIZED,
+ UNSUPPORTED,
+ PERFORMANCE,
+ DEPRECATION,
+ GENERIC;
+ }
+
+ public static Optional valueOf(String value) {
+ return Arrays.stream(Type.values())
+ .filter(type -> type.toString().equals(value))
+ .findFirst()
+ .map(type -> switch (type) {
+ case HINT -> NotificationCategory.HINT;
+ case UNRECOGNIZED -> NotificationCategory.UNRECOGNIZED;
+ case UNSUPPORTED -> NotificationCategory.UNSUPPORTED;
+ case PERFORMANCE -> NotificationCategory.PERFORMANCE;
+ case DEPRECATION -> NotificationCategory.DEPRECATION;
+ case GENERIC -> NotificationCategory.GENERIC;
+ });
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationConfig.java b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationConfig.java
new file mode 100644
index 0000000000..4949fba500
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationConfig.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal;
+
+import java.util.Objects;
+import java.util.Set;
+import org.neo4j.driver.NotificationCategory;
+import org.neo4j.driver.NotificationConfig;
+import org.neo4j.driver.NotificationSeverity;
+
+public record InternalNotificationConfig(
+ NotificationSeverity minimumSeverity, Set disabledCategories)
+ implements NotificationConfig {
+ @Override
+ public NotificationConfig enableMinimumSeverity(NotificationSeverity minimumSeverity) {
+ Objects.requireNonNull(minimumSeverity, "minimumSeverity must not be null");
+ return new InternalNotificationConfig(minimumSeverity, disabledCategories);
+ }
+
+ @Override
+ public NotificationConfig disableCategories(Set disabledCategories) {
+ Objects.requireNonNull(disabledCategories, "disabledCategories must not be null");
+ return new InternalNotificationConfig(minimumSeverity, Set.copyOf(disabledCategories));
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationSeverity.java b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationSeverity.java
new file mode 100644
index 0000000000..935872425e
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/InternalNotificationSeverity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Optional;
+import org.neo4j.driver.NotificationSeverity;
+
+public record InternalNotificationSeverity(Type type, int level) implements NotificationSeverity {
+ public static final InternalNotificationSeverity OFF =
+ new InternalNotificationSeverity(Type.OFF, Integer.MAX_VALUE);
+
+ public InternalNotificationSeverity {
+ Objects.requireNonNull(type, "type must not be null");
+ }
+
+ @Override
+ public int compareTo(NotificationSeverity severity) {
+ return Integer.compare(level, ((InternalNotificationSeverity) severity).level());
+ }
+
+ public enum Type {
+ INFORMATION,
+ WARNING,
+ OFF
+ }
+
+ public static Optional valueOf(String value) {
+ return Arrays.stream(Type.values())
+ .filter(type -> type.toString().equals(value))
+ .findFirst()
+ .map(type -> switch (type) {
+ case INFORMATION -> NotificationSeverity.INFORMATION;
+ case WARNING -> NotificationSeverity.WARNING;
+ case OFF -> InternalNotificationSeverity.OFF;
+ });
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java
index 7fd41280ad..737ebd8d3d 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java
@@ -29,6 +29,7 @@
import org.neo4j.driver.BookmarkManager;
import org.neo4j.driver.Config;
import org.neo4j.driver.Logging;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.SessionConfig;
import org.neo4j.driver.internal.async.LeakLoggingNetworkSession;
import org.neo4j.driver.internal.async.NetworkSession;
@@ -41,6 +42,7 @@ public class SessionFactoryImpl implements SessionFactory {
private final Logging logging;
private final boolean leakedSessionsLoggingEnabled;
private final long defaultFetchSize;
+ private final NotificationConfig driverNotificationConfig;
SessionFactoryImpl(ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config) {
this.connectionProvider = connectionProvider;
@@ -48,6 +50,7 @@ public class SessionFactoryImpl implements SessionFactory {
this.retryLogic = retryLogic;
this.logging = config.logging();
this.defaultFetchSize = config.fetchSize();
+ this.driverNotificationConfig = config.notificationConfig();
}
@Override
@@ -61,7 +64,8 @@ public NetworkSession newInstance(SessionConfig sessionConfig) {
parseFetchSize(sessionConfig),
sessionConfig.impersonatedUser().orElse(null),
logging,
- sessionConfig.bookmarkManager().orElse(NoOpBookmarkManager.INSTANCE));
+ sessionConfig.bookmarkManager().orElse(NoOpBookmarkManager.INSTANCE),
+ sessionConfig.notificationConfig());
}
private Set toDistinctSet(Iterable bookmarks) {
@@ -131,7 +135,8 @@ private NetworkSession createSession(
long fetchSize,
String impersonatedUser,
Logging logging,
- BookmarkManager bookmarkManager) {
+ BookmarkManager bookmarkManager,
+ NotificationConfig notificationConfig) {
Objects.requireNonNull(bookmarks, "bookmarks may not be null");
Objects.requireNonNull(bookmarkManager, "bookmarkManager may not be null");
return leakedSessionsLoggingEnabled
@@ -144,7 +149,8 @@ private NetworkSession createSession(
impersonatedUser,
fetchSize,
logging,
- bookmarkManager)
+ bookmarkManager,
+ notificationConfig)
: new NetworkSession(
connectionProvider,
retryLogic,
@@ -154,6 +160,7 @@ private NetworkSession createSession(
impersonatedUser,
fetchSize,
logging,
- bookmarkManager);
+ bookmarkManager,
+ notificationConfig);
}
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java
index 86985059ee..266fbb61b4 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java
@@ -25,6 +25,7 @@
import org.neo4j.driver.Bookmark;
import org.neo4j.driver.BookmarkManager;
import org.neo4j.driver.Logging;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.internal.DatabaseName;
import org.neo4j.driver.internal.retry.RetryLogic;
import org.neo4j.driver.internal.spi.ConnectionProvider;
@@ -42,7 +43,8 @@ public LeakLoggingNetworkSession(
String impersonatedUser,
long fetchSize,
Logging logging,
- BookmarkManager bookmarkManager) {
+ BookmarkManager bookmarkManager,
+ NotificationConfig notificationConfig) {
super(
connectionProvider,
retryLogic,
@@ -52,7 +54,8 @@ public LeakLoggingNetworkSession(
impersonatedUser,
fetchSize,
logging,
- bookmarkManager);
+ bookmarkManager,
+ notificationConfig);
this.stackTrace = captureStackTrace();
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java
index 016df32f30..79cad9010e 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java
@@ -36,6 +36,7 @@
import org.neo4j.driver.BookmarkManager;
import org.neo4j.driver.Logger;
import org.neo4j.driver.Logging;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Query;
import org.neo4j.driver.TransactionConfig;
import org.neo4j.driver.async.ResultCursor;
@@ -75,6 +76,7 @@ public class NetworkSession {
private final BookmarkManager bookmarkManager;
private volatile Set lastUsedBookmarks = Collections.emptySet();
private volatile Set lastReceivedBookmarks;
+ private final NotificationConfig notificationConfig;
public NetworkSession(
ConnectionProvider connectionProvider,
@@ -85,7 +87,8 @@ public NetworkSession(
String impersonatedUser,
long fetchSize,
Logging logging,
- BookmarkManager bookmarkManager) {
+ BookmarkManager bookmarkManager,
+ NotificationConfig notificationConfig) {
Objects.requireNonNull(bookmarks, "bookmarks may not be null");
Objects.requireNonNull(bookmarkManager, "bookmarkManager may not be null");
this.connectionProvider = connectionProvider;
@@ -101,6 +104,7 @@ public NetworkSession(
this.connectionContext =
new NetworkSessionConnectionContext(databaseNameFuture, determineBookmarks(false), impersonatedUser);
this.fetchSize = fetchSize;
+ this.notificationConfig = notificationConfig;
}
public CompletionStage runAsync(Query query, TransactionConfig config) {
@@ -143,7 +147,8 @@ public CompletionStage beginTransactionAsync(
.thenApply(connection ->
ImpersonationUtil.ensureImpersonationSupport(connection, connection.impersonatedUser()))
.thenCompose(connection -> {
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, this::handleNewBookmark, fetchSize);
+ UnmanagedTransaction tx = new UnmanagedTransaction(
+ connection, this::handleNewBookmark, fetchSize, notificationConfig);
return tx.beginAsync(determineBookmarks(true), config, txType);
});
@@ -259,7 +264,8 @@ private CompletionStage buildResultCursorFactory(Query quer
determineBookmarks(true),
this::handleNewBookmark,
config,
- fetchSize);
+ fetchSize,
+ notificationConfig);
return completedFuture(factory);
} catch (Throwable e) {
return Futures.failedFuture(e);
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java
index 677079c7fb..69786ece57 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java
@@ -37,6 +37,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Query;
import org.neo4j.driver.TransactionConfig;
import org.neo4j.driver.async.ResultCursor;
@@ -93,26 +94,33 @@ private enum State {
private CompletableFuture rollbackFuture;
private Throwable causeOfTermination;
private CompletionStage interruptStage;
+ private final NotificationConfig notificationConfig;
- public UnmanagedTransaction(Connection connection, Consumer bookmarkConsumer, long fetchSize) {
- this(connection, bookmarkConsumer, fetchSize, new ResultCursorsHolder());
+ public UnmanagedTransaction(
+ Connection connection,
+ Consumer bookmarkConsumer,
+ long fetchSize,
+ NotificationConfig notificationConfig) {
+ this(connection, bookmarkConsumer, fetchSize, new ResultCursorsHolder(), notificationConfig);
}
protected UnmanagedTransaction(
Connection connection,
Consumer bookmarkConsumer,
long fetchSize,
- ResultCursorsHolder resultCursors) {
+ ResultCursorsHolder resultCursors,
+ NotificationConfig notificationConfig) {
this.connection = connection;
this.protocol = connection.protocol();
this.bookmarkConsumer = bookmarkConsumer;
this.resultCursors = resultCursors;
this.fetchSize = fetchSize;
+ this.notificationConfig = notificationConfig;
}
public CompletionStage beginAsync(
Set initialBookmarks, TransactionConfig config, String txType) {
- return protocol.beginTransaction(connection, initialBookmarks, config, txType)
+ return protocol.beginTransaction(connection, initialBookmarks, config, txType, notificationConfig)
.handle((ignore, beginError) -> {
if (beginError != null) {
if (beginError instanceof AuthorizationExpiredException) {
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java
index 1ff165865b..c87d2cab7e 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java
@@ -29,6 +29,7 @@
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
+import org.neo4j.driver.internal.messaging.v52.BoltProtocolV52;
public final class BoltProtocolUtil {
public static final int BOLT_MAGIC_PREAMBLE = 0x6060B017;
@@ -40,7 +41,7 @@ public final class BoltProtocolUtil {
private static final ByteBuf HANDSHAKE_BUF = unreleasableBuffer(copyInt(
BOLT_MAGIC_PREAMBLE,
- BoltProtocolV5.VERSION.toInt(),
+ BoltProtocolV52.VERSION.toIntRange(BoltProtocolV5.VERSION),
BoltProtocolV44.VERSION.toIntRange(BoltProtocolV42.VERSION),
BoltProtocolV41.VERSION.toInt(),
BoltProtocolV3.VERSION.toInt()))
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java
index 35a6ffc08d..4f76e8a79c 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectorImpl.java
@@ -32,6 +32,7 @@
import java.time.Clock;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.Logging;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.internal.BoltServerAddress;
import org.neo4j.driver.internal.ConnectionSettings;
import org.neo4j.driver.internal.DomainNameResolver;
@@ -50,6 +51,7 @@ public class ChannelConnectorImpl implements ChannelConnector {
private final Clock clock;
private final DomainNameResolver domainNameResolver;
private final AddressResolverGroup addressResolverGroup;
+ private final NotificationConfig notificationConfig;
public ChannelConnectorImpl(
ConnectionSettings connectionSettings,
@@ -57,7 +59,8 @@ public ChannelConnectorImpl(
Logging logging,
Clock clock,
RoutingContext routingContext,
- DomainNameResolver domainNameResolver) {
+ DomainNameResolver domainNameResolver,
+ NotificationConfig notificationConfig) {
this(
connectionSettings,
securityPlan,
@@ -65,7 +68,8 @@ public ChannelConnectorImpl(
logging,
clock,
routingContext,
- domainNameResolver);
+ domainNameResolver,
+ notificationConfig);
}
public ChannelConnectorImpl(
@@ -75,7 +79,8 @@ public ChannelConnectorImpl(
Logging logging,
Clock clock,
RoutingContext routingContext,
- DomainNameResolver domainNameResolver) {
+ DomainNameResolver domainNameResolver,
+ NotificationConfig notificationConfig) {
this.userAgent = connectionSettings.userAgent();
this.authToken = connectionSettings.authToken();
this.routingContext = routingContext;
@@ -86,6 +91,7 @@ public ChannelConnectorImpl(
this.clock = requireNonNull(clock);
this.domainNameResolver = requireNonNull(domainNameResolver);
this.addressResolverGroup = new NettyDomainNameResolverGroup(this.domainNameResolver);
+ this.notificationConfig = notificationConfig;
}
@Override
@@ -137,7 +143,7 @@ private void installHandshakeCompletedListeners(
// add listener that sends an INIT message. connection is now fully established. channel pipeline if fully
// set to send/receive messages for a selected protocol version
- handshakeCompleted.addListener(
- new HandshakeCompletedListener(userAgent, authToken, routingContext, connectionInitialized));
+ handshakeCompleted.addListener(new HandshakeCompletedListener(
+ userAgent, authToken, routingContext, connectionInitialized, notificationConfig));
}
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java
index 2a9f3e5953..3fdda59ca9 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java
@@ -24,6 +24,7 @@
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelPromise;
import org.neo4j.driver.AuthToken;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.internal.cluster.RoutingContext;
import org.neo4j.driver.internal.messaging.BoltProtocol;
@@ -32,23 +33,27 @@ public class HandshakeCompletedListener implements ChannelFutureListener {
private final AuthToken authToken;
private final RoutingContext routingContext;
private final ChannelPromise connectionInitializedPromise;
+ private final NotificationConfig notificationConfig;
public HandshakeCompletedListener(
String userAgent,
AuthToken authToken,
RoutingContext routingContext,
- ChannelPromise connectionInitializedPromise) {
+ ChannelPromise connectionInitializedPromise,
+ NotificationConfig notificationConfig) {
this.userAgent = requireNonNull(userAgent);
this.authToken = requireNonNull(authToken);
this.routingContext = routingContext;
this.connectionInitializedPromise = requireNonNull(connectionInitializedPromise);
+ this.notificationConfig = notificationConfig;
}
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
BoltProtocol protocol = BoltProtocol.forChannel(future.channel());
- protocol.initializeChannel(userAgent, authToken, routingContext, connectionInitializedPromise);
+ protocol.initializeChannel(
+ userAgent, authToken, routingContext, connectionInitializedPromise, notificationConfig);
} else {
connectionInitializedPromise.setFailure(future.cause());
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
index 9d58ed32f2..4b4c0524d0 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java
@@ -43,6 +43,7 @@
import org.neo4j.driver.exceptions.FatalDiscoveryException;
import org.neo4j.driver.exceptions.SecurityException;
import org.neo4j.driver.exceptions.ServiceUnavailableException;
+import org.neo4j.driver.exceptions.UnsupportedFeatureException;
import org.neo4j.driver.internal.BoltServerAddress;
import org.neo4j.driver.internal.DomainNameResolver;
import org.neo4j.driver.internal.ImpersonationUtil;
@@ -296,6 +297,8 @@ private boolean mustAbortDiscovery(Throwable throwable) {
} else if (throwable instanceof IllegalStateException
&& ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE.equals(throwable.getMessage())) {
abort = true;
+ } else if (throwable instanceof UnsupportedFeatureException) {
+ abort = true;
} else if (throwable instanceof ClientException) {
String code = ((ClientException) throwable).code();
abort = switch (code) {
diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java
index 3a8e424694..127e71069e 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java
@@ -92,7 +92,8 @@ CompletionStage> runProcedure(Connection connection, Query procedur
bookmarks,
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE)
+ UNLIMITED_FETCH_SIZE,
+ null)
.asyncResult()
.thenCompose(ResultCursor::listAsync);
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/LogonResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/LogonResponseHandler.java
new file mode 100644
index 0000000000..acbad6fc42
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/LogonResponseHandler.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.handlers;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelPromise;
+import java.util.Map;
+import org.neo4j.driver.Value;
+import org.neo4j.driver.exceptions.ProtocolException;
+import org.neo4j.driver.internal.spi.ResponseHandler;
+
+public class LogonResponseHandler implements ResponseHandler {
+
+ private final ChannelPromise connectionInitializedPromise;
+ private final Channel channel;
+
+ public LogonResponseHandler(ChannelPromise connectionInitializedPromise) {
+ this.connectionInitializedPromise = connectionInitializedPromise;
+ this.channel = connectionInitializedPromise.channel();
+ }
+
+ @Override
+ public void onSuccess(Map metadata) {
+ connectionInitializedPromise.setSuccess();
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ channel.close().addListener(future -> connectionInitializedPromise.setFailure(error));
+ }
+
+ @Override
+ public void onRecord(Value[] fields) {
+ throw new ProtocolException("records not supported");
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java
index 315078606e..0e55baffc2 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java
@@ -27,6 +27,7 @@
import java.util.function.Consumer;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Query;
import org.neo4j.driver.Session;
import org.neo4j.driver.Transaction;
@@ -43,6 +44,8 @@
import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43;
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
+import org.neo4j.driver.internal.messaging.v51.BoltProtocolV51;
+import org.neo4j.driver.internal.messaging.v52.BoltProtocolV52;
import org.neo4j.driver.internal.spi.Connection;
public interface BoltProtocol {
@@ -56,16 +59,18 @@ public interface BoltProtocol {
/**
* Initialize channel after it is connected and handshake selected this protocol version.
*
- * @param userAgent the user agent string.
- * @param authToken the authentication token.
- * @param routingContext the configured routing context
+ * @param userAgent the user agent string.
+ * @param authToken the authentication token.
+ * @param routingContext the configured routing context
* @param channelInitializedPromise the promise to be notified when initialization is completed.
+ * @param notificationConfig the notification configuration
*/
void initializeChannel(
String userAgent,
AuthToken authToken,
RoutingContext routingContext,
- ChannelPromise channelInitializedPromise);
+ ChannelPromise channelInitializedPromise,
+ NotificationConfig notificationConfig);
/**
* Prepare to close channel before it is closed.
@@ -76,14 +81,19 @@ void initializeChannel(
/**
* Begin an unmanaged transaction.
*
- * @param connection the connection to use.
- * @param bookmarks the bookmarks. Never null, should be empty when there are no bookmarks.
- * @param config the transaction configuration. Never null, should be {@link TransactionConfig#empty()} when absent.
- * @param txType the Kernel transaction type
+ * @param connection the connection to use.
+ * @param bookmarks the bookmarks. Never null, should be empty when there are no bookmarks.
+ * @param config the transaction configuration. Never null, should be {@link TransactionConfig#empty()} when absent.
+ * @param txType the Kernel transaction type
+ * @param notificationConfig the notification configuration
* @return a completion stage completed when transaction is started or completed exceptionally when there was a failure.
*/
CompletionStage beginTransaction(
- Connection connection, Set bookmarks, TransactionConfig config, String txType);
+ Connection connection,
+ Set bookmarks,
+ TransactionConfig config,
+ String txType,
+ NotificationConfig notificationConfig);
/**
* Commit the unmanaged transaction.
@@ -104,11 +114,12 @@ CompletionStage beginTransaction(
/**
* Execute the given query in an auto-commit transaction, i.e. {@link Session#run(Query)}.
*
- * @param connection the network connection to use.
- * @param query the cypher to execute.
- * @param bookmarkConsumer the database bookmark consumer.
- * @param config the transaction config for the implicitly started auto-commit transaction.
- * @param fetchSize the record fetch size for PULL message.
+ * @param connection the network connection to use.
+ * @param query the cypher to execute.
+ * @param bookmarkConsumer the database bookmark consumer.
+ * @param config the transaction config for the implicitly started auto-commit transaction.
+ * @param fetchSize the record fetch size for PULL message.
+ * @param notificationConfig the notification configuration
* @return stage with cursor.
*/
ResultCursorFactory runInAutoCommitTransaction(
@@ -117,7 +128,8 @@ ResultCursorFactory runInAutoCommitTransaction(
Set bookmarks,
Consumer bookmarkConsumer,
TransactionConfig config,
- long fetchSize);
+ long fetchSize,
+ NotificationConfig notificationConfig);
/**
* Execute the given query in a running unmanaged transaction, i.e. {@link Transaction#run(Query)}.
@@ -170,6 +182,10 @@ static BoltProtocol forVersion(BoltProtocolVersion version) {
return BoltProtocolV44.INSTANCE;
} else if (BoltProtocolV5.VERSION.equals(version)) {
return BoltProtocolV5.INSTANCE;
+ } else if (BoltProtocolV51.VERSION.equals(version)) {
+ return BoltProtocolV51.INSTANCE;
+ } else if (BoltProtocolV52.VERSION.equals(version)) {
+ return BoltProtocolV52.INSTANCE;
}
throw new ClientException("Unknown protocol version: " + version);
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/LogonMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/LogonMessageEncoder.java
new file mode 100644
index 0000000000..d5e4805f6e
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/LogonMessageEncoder.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.encode;
+
+import static org.neo4j.driver.internal.util.Preconditions.checkArgument;
+
+import java.io.IOException;
+import org.neo4j.driver.internal.messaging.Message;
+import org.neo4j.driver.internal.messaging.MessageEncoder;
+import org.neo4j.driver.internal.messaging.ValuePacker;
+import org.neo4j.driver.internal.messaging.request.LogonMessage;
+
+public class LogonMessageEncoder implements MessageEncoder {
+ @Override
+ public void encode(Message message, ValuePacker packer) throws IOException {
+ checkArgument(message, LogonMessage.class);
+ var logonMessage = (LogonMessage) message;
+ packer.packStructHeader(1, logonMessage.signature());
+ packer.pack(logonMessage.metadata());
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java
index bdc4180e69..0b599a3169 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java
@@ -26,6 +26,7 @@
import java.util.Set;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.TransactionConfig;
import org.neo4j.driver.Value;
import org.neo4j.driver.internal.DatabaseName;
@@ -39,8 +40,17 @@ public BeginMessage(
DatabaseName databaseName,
AccessMode mode,
String impersonatedUser,
- String txType) {
- this(bookmarks, config.timeout(), config.metadata(), mode, databaseName, impersonatedUser, txType);
+ String txType,
+ NotificationConfig notificationConfig) {
+ this(
+ bookmarks,
+ config.timeout(),
+ config.metadata(),
+ mode,
+ databaseName,
+ impersonatedUser,
+ txType,
+ notificationConfig);
}
public BeginMessage(
@@ -50,8 +60,10 @@ public BeginMessage(
AccessMode mode,
DatabaseName databaseName,
String impersonatedUser,
- String txType) {
- super(buildMetadata(txTimeout, txMetadata, databaseName, mode, bookmarks, impersonatedUser, txType));
+ String txType,
+ NotificationConfig notificationConfig) {
+ super(buildMetadata(
+ txTimeout, txMetadata, databaseName, mode, bookmarks, impersonatedUser, txType, notificationConfig));
}
@Override
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java
index 4d0abe8859..846632350d 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java
@@ -25,6 +25,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Value;
public class HelloMessage extends MessageWithMetadata {
@@ -40,8 +41,9 @@ public HelloMessage(
String userAgent,
Map authToken,
Map routingContext,
- boolean includeDateTimeUtc) {
- super(buildMetadata(userAgent, authToken, routingContext, includeDateTimeUtc));
+ boolean includeDateTimeUtc,
+ NotificationConfig notificationConfig) {
+ super(buildMetadata(userAgent, authToken, routingContext, includeDateTimeUtc, notificationConfig));
}
@Override
@@ -77,7 +79,8 @@ private static Map buildMetadata(
String userAgent,
Map authToken,
Map routingContext,
- boolean includeDateTimeUtc) {
+ boolean includeDateTimeUtc,
+ NotificationConfig notificationConfig) {
Map result = new HashMap<>(authToken);
result.put(USER_AGENT_METADATA_KEY, value(userAgent));
if (routingContext != null) {
@@ -86,6 +89,7 @@ private static Map buildMetadata(
if (includeDateTimeUtc) {
result.put(PATCH_BOLT_METADATA_KEY, value(Collections.singleton(DATE_TIME_UTC_PATCH_VALUE)));
}
+ MessageWithMetadata.appendNotificationConfig(result, notificationConfig);
return result;
}
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/LogonMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/LogonMessage.java
new file mode 100644
index 0000000000..8cbe4c45ed
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/LogonMessage.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.request;
+
+import static org.neo4j.driver.Values.value;
+import static org.neo4j.driver.internal.security.InternalAuthToken.CREDENTIALS_KEY;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.neo4j.driver.Value;
+
+public class LogonMessage extends MessageWithMetadata {
+ public static final byte SIGNATURE = 0x6A;
+
+ public LogonMessage(Map authToken) {
+ super(authToken);
+ }
+
+ @Override
+ public byte signature() {
+ return SIGNATURE;
+ }
+
+ @Override
+ public String toString() {
+ Map metadataCopy = new HashMap<>(metadata());
+ metadataCopy.replace(CREDENTIALS_KEY, value("******"));
+ return "LOGON " + metadataCopy;
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java
index 76aa05be48..3433dc0087 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java
@@ -18,11 +18,19 @@
*/
package org.neo4j.driver.internal.messaging.request;
+import static org.neo4j.driver.Values.value;
+
import java.util.Map;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Value;
+import org.neo4j.driver.internal.InternalNotificationCategory;
+import org.neo4j.driver.internal.InternalNotificationConfig;
+import org.neo4j.driver.internal.InternalNotificationSeverity;
import org.neo4j.driver.internal.messaging.Message;
abstract class MessageWithMetadata implements Message {
+ static final String NOTIFICATIONS_MINIMUM_SEVERITY = "notifications_minimum_severity";
+ static final String NOTIFICATIONS_DISABLED_CATEGORIES = "notifications_disabled_categories";
private final Map metadata;
public MessageWithMetadata(Map metadata) {
@@ -32,4 +40,25 @@ public MessageWithMetadata(Map metadata) {
public Map metadata() {
return metadata;
}
+
+ static void appendNotificationConfig(Map result, NotificationConfig config) {
+ if (config != null) {
+ if (config instanceof InternalNotificationConfig internalConfig) {
+ var severity = (InternalNotificationSeverity) internalConfig.minimumSeverity();
+ if (severity != null) {
+ result.put(
+ NOTIFICATIONS_MINIMUM_SEVERITY,
+ value(severity.type().toString()));
+ }
+ var disabledCategories = internalConfig.disabledCategories();
+ if (disabledCategories != null) {
+ var list = disabledCategories.stream()
+ .map(category -> (InternalNotificationCategory) category)
+ .map(category -> category.type().toString())
+ .toList();
+ result.put(NOTIFICATIONS_DISABLED_CATEGORIES, value(list));
+ }
+ }
+ }
+ }
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java
index 50fd53f426..2bb7a1f677 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java
@@ -28,6 +28,7 @@
import java.util.Set;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Query;
import org.neo4j.driver.TransactionConfig;
import org.neo4j.driver.Value;
@@ -45,9 +46,17 @@ public static RunWithMetadataMessage autoCommitTxRunMessage(
DatabaseName databaseName,
AccessMode mode,
Set bookmarks,
- String impersonatedUser) {
+ String impersonatedUser,
+ NotificationConfig notificationConfig) {
return autoCommitTxRunMessage(
- query, config.timeout(), config.metadata(), databaseName, mode, bookmarks, impersonatedUser);
+ query,
+ config.timeout(),
+ config.metadata(),
+ databaseName,
+ mode,
+ bookmarks,
+ impersonatedUser,
+ notificationConfig);
}
public static RunWithMetadataMessage autoCommitTxRunMessage(
@@ -57,9 +66,10 @@ public static RunWithMetadataMessage autoCommitTxRunMessage(
DatabaseName databaseName,
AccessMode mode,
Set bookmarks,
- String impersonatedUser) {
- Map metadata =
- buildMetadata(txTimeout, txMetadata, databaseName, mode, bookmarks, impersonatedUser, null);
+ String impersonatedUser,
+ NotificationConfig notificationConfig) {
+ Map metadata = buildMetadata(
+ txTimeout, txMetadata, databaseName, mode, bookmarks, impersonatedUser, null, notificationConfig);
return new RunWithMetadataMessage(query.text(), query.parameters().asMap(ofValue()), metadata);
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java
index 36ab5a1d0b..4fd7de2f98 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java
@@ -27,6 +27,7 @@
import java.util.Set;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Value;
import org.neo4j.driver.internal.DatabaseName;
import org.neo4j.driver.internal.util.Iterables;
@@ -48,7 +49,7 @@ public static Map buildMetadata(
Set bookmarks,
String impersonatedUser,
String txType) {
- return buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, impersonatedUser, txType);
+ return buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, impersonatedUser, txType, null);
}
public static Map buildMetadata(
@@ -58,7 +59,8 @@ public static Map buildMetadata(
AccessMode mode,
Set bookmarks,
String impersonatedUser,
- String txType) {
+ String txType,
+ NotificationConfig notificationConfig) {
boolean bookmarksPresent = !bookmarks.isEmpty();
boolean txTimeoutPresent = txTimeout != null;
boolean txMetadataPresent = txMetadata != null && !txMetadata.isEmpty();
@@ -97,6 +99,7 @@ public static Map buildMetadata(
if (txTypePresent) {
result.put(TX_TYPE_KEY, value(txType));
}
+ MessageWithMetadata.appendNotificationConfig(result, notificationConfig);
databaseName.databaseName().ifPresent(name -> result.put(DATABASE_NAME_KEY, value(name)));
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java
index 5919104f02..a5f964d777 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java
@@ -34,8 +34,11 @@
import java.util.function.Consumer;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.Bookmark;
+import org.neo4j.driver.NotificationConfig;
import org.neo4j.driver.Query;
import org.neo4j.driver.TransactionConfig;
+import org.neo4j.driver.exceptions.Neo4jException;
+import org.neo4j.driver.exceptions.UnsupportedFeatureException;
import org.neo4j.driver.internal.DatabaseBookmark;
import org.neo4j.driver.internal.DatabaseName;
import org.neo4j.driver.internal.async.UnmanagedTransaction;
@@ -79,7 +82,13 @@ public void initializeChannel(
String userAgent,
AuthToken authToken,
RoutingContext routingContext,
- ChannelPromise channelInitializedPromise) {
+ ChannelPromise channelInitializedPromise,
+ NotificationConfig notificationConfig) {
+ var exception = verifyNotificationConfigSupported(notificationConfig);
+ if (exception != null) {
+ channelInitializedPromise.setFailure(exception);
+ return;
+ }
Channel channel = channelInitializedPromise.channel();
HelloMessage message;
@@ -88,10 +97,15 @@ public void initializeChannel(
userAgent,
((InternalAuthToken) authToken).toMap(),
routingContext.toMap(),
- includeDateTimeUtcPatchInHello());
+ includeDateTimeUtcPatchInHello(),
+ notificationConfig);
} else {
message = new HelloMessage(
- userAgent, ((InternalAuthToken) authToken).toMap(), null, includeDateTimeUtcPatchInHello());
+ userAgent,
+ ((InternalAuthToken) authToken).toMap(),
+ null,
+ includeDateTimeUtcPatchInHello(),
+ notificationConfig);
}
HelloResponseHandler handler = new HelloResponseHandler(channelInitializedPromise);
@@ -113,7 +127,15 @@ public void prepareToCloseChannel(Channel channel) {
@Override
public CompletionStage beginTransaction(
- Connection connection, Set bookmarks, TransactionConfig config, String txType) {
+ Connection connection,
+ Set bookmarks,
+ TransactionConfig config,
+ String txType,
+ NotificationConfig notificationConfig) {
+ var exception = verifyNotificationConfigSupported(notificationConfig);
+ if (exception != null) {
+ return CompletableFuture.failedStage(exception);
+ }
try {
verifyDatabaseNameBeforeTransaction(connection.databaseName());
} catch (Exception error) {
@@ -122,7 +144,13 @@ public CompletionStage beginTransaction(
CompletableFuture beginTxFuture = new CompletableFuture<>();
BeginMessage beginMessage = new BeginMessage(
- bookmarks, config, connection.databaseName(), connection.mode(), connection.impersonatedUser(), txType);
+ bookmarks,
+ config,
+ connection.databaseName(),
+ connection.mode(),
+ connection.impersonatedUser(),
+ txType,
+ notificationConfig);
connection.writeAndFlush(beginMessage, new BeginTxResponseHandler(beginTxFuture));
return beginTxFuture;
}
@@ -148,10 +176,21 @@ public ResultCursorFactory runInAutoCommitTransaction(
Set bookmarks,
Consumer bookmarkConsumer,
TransactionConfig config,
- long fetchSize) {
+ long fetchSize,
+ NotificationConfig notificationConfig) {
+ var exception = verifyNotificationConfigSupported(notificationConfig);
+ if (exception != null) {
+ throw exception;
+ }
verifyDatabaseNameBeforeTransaction(connection.databaseName());
RunWithMetadataMessage runMessage = autoCommitTxRunMessage(
- query, config, connection.databaseName(), connection.mode(), bookmarks, connection.impersonatedUser());
+ query,
+ config,
+ connection.databaseName(),
+ connection.mode(),
+ bookmarks,
+ connection.impersonatedUser(),
+ notificationConfig);
return buildResultCursorFactory(connection, query, bookmarkConsumer, null, runMessage, fetchSize);
}
@@ -189,4 +228,14 @@ public BoltProtocolVersion version() {
protected boolean includeDateTimeUtcPatchInHello() {
return false;
}
+
+ protected Neo4jException verifyNotificationConfigSupported(NotificationConfig notificationConfig) {
+ Neo4jException exception = null;
+ if (notificationConfig != null && !notificationConfig.equals(NotificationConfig.defaultConfig())) {
+ exception = new UnsupportedFeatureException(String.format(
+ "Notification configuration is not supported on Bolt %s",
+ version().toString()));
+ }
+ return exception;
+ }
}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/BoltProtocolV51.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/BoltProtocolV51.java
new file mode 100644
index 0000000000..a667f1247d
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/BoltProtocolV51.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.v51;
+
+import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher;
+
+import io.netty.channel.ChannelPromise;
+import java.util.Collections;
+import org.neo4j.driver.AuthToken;
+import org.neo4j.driver.NotificationConfig;
+import org.neo4j.driver.internal.cluster.RoutingContext;
+import org.neo4j.driver.internal.handlers.HelloResponseHandler;
+import org.neo4j.driver.internal.handlers.LogonResponseHandler;
+import org.neo4j.driver.internal.messaging.BoltProtocol;
+import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
+import org.neo4j.driver.internal.messaging.MessageFormat;
+import org.neo4j.driver.internal.messaging.request.HelloMessage;
+import org.neo4j.driver.internal.messaging.request.LogonMessage;
+import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
+import org.neo4j.driver.internal.security.InternalAuthToken;
+
+public class BoltProtocolV51 extends BoltProtocolV5 {
+ public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(5, 1);
+ public static final BoltProtocol INSTANCE = new BoltProtocolV51();
+
+ @Override
+ public void initializeChannel(
+ String userAgent,
+ AuthToken authToken,
+ RoutingContext routingContext,
+ ChannelPromise channelInitializedPromise,
+ NotificationConfig notificationConfig) {
+ var exception = verifyNotificationConfigSupported(notificationConfig);
+ if (exception != null) {
+ channelInitializedPromise.setFailure(exception);
+ return;
+ }
+ var channel = channelInitializedPromise.channel();
+ HelloMessage message;
+
+ if (routingContext.isServerRoutingEnabled()) {
+ message = new HelloMessage(
+ userAgent, Collections.emptyMap(), routingContext.toMap(), false, notificationConfig);
+ } else {
+ message = new HelloMessage(userAgent, Collections.emptyMap(), null, false, notificationConfig);
+ }
+
+ messageDispatcher(channel).enqueue(new HelloResponseHandler(channel.voidPromise()));
+ messageDispatcher(channel).enqueue(new LogonResponseHandler(channelInitializedPromise));
+ channel.write(message, channel.voidPromise());
+ channel.writeAndFlush(new LogonMessage(((InternalAuthToken) authToken).toMap()));
+ }
+
+ @Override
+ public BoltProtocolVersion version() {
+ return VERSION;
+ }
+
+ @Override
+ public MessageFormat createMessageFormat() {
+ return new MessageFormatV51();
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageFormatV51.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageFormatV51.java
new file mode 100644
index 0000000000..96112e4f80
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageFormatV51.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.v51;
+
+import org.neo4j.driver.internal.messaging.MessageFormat;
+import org.neo4j.driver.internal.messaging.v5.MessageReaderV5;
+import org.neo4j.driver.internal.packstream.PackInput;
+import org.neo4j.driver.internal.packstream.PackOutput;
+
+public class MessageFormatV51 implements MessageFormat {
+ @Override
+ public Writer newWriter(PackOutput output) {
+ return new MessageWriterV51(output);
+ }
+
+ @Override
+ public Reader newReader(PackInput input) {
+ return new MessageReaderV5(input);
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageWriterV51.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageWriterV51.java
new file mode 100644
index 0000000000..d36f8af518
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v51/MessageWriterV51.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.v51;
+
+import java.util.Map;
+import org.neo4j.driver.internal.messaging.AbstractMessageWriter;
+import org.neo4j.driver.internal.messaging.MessageEncoder;
+import org.neo4j.driver.internal.messaging.common.CommonValuePacker;
+import org.neo4j.driver.internal.messaging.encode.BeginMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.CommitMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.DiscardMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.GoodbyeMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.HelloMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.LogonMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.PullMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.ResetMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.RollbackMessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.RouteV44MessageEncoder;
+import org.neo4j.driver.internal.messaging.encode.RunWithMetadataMessageEncoder;
+import org.neo4j.driver.internal.messaging.request.BeginMessage;
+import org.neo4j.driver.internal.messaging.request.CommitMessage;
+import org.neo4j.driver.internal.messaging.request.DiscardMessage;
+import org.neo4j.driver.internal.messaging.request.GoodbyeMessage;
+import org.neo4j.driver.internal.messaging.request.HelloMessage;
+import org.neo4j.driver.internal.messaging.request.LogonMessage;
+import org.neo4j.driver.internal.messaging.request.PullMessage;
+import org.neo4j.driver.internal.messaging.request.ResetMessage;
+import org.neo4j.driver.internal.messaging.request.RollbackMessage;
+import org.neo4j.driver.internal.messaging.request.RouteMessage;
+import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage;
+import org.neo4j.driver.internal.packstream.PackOutput;
+import org.neo4j.driver.internal.util.Iterables;
+
+public class MessageWriterV51 extends AbstractMessageWriter {
+ public MessageWriterV51(PackOutput output) {
+ super(new CommonValuePacker(output, true), buildEncoders());
+ }
+
+ private static Map buildEncoders() {
+ Map result = Iterables.newHashMapWithSize(9);
+ result.put(HelloMessage.SIGNATURE, new HelloMessageEncoder());
+ result.put(LogonMessage.SIGNATURE, new LogonMessageEncoder());
+ result.put(GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder());
+ result.put(RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder());
+ result.put(RouteMessage.SIGNATURE, new RouteV44MessageEncoder());
+
+ result.put(DiscardMessage.SIGNATURE, new DiscardMessageEncoder());
+ result.put(PullMessage.SIGNATURE, new PullMessageEncoder());
+
+ result.put(BeginMessage.SIGNATURE, new BeginMessageEncoder());
+ result.put(CommitMessage.SIGNATURE, new CommitMessageEncoder());
+ result.put(RollbackMessage.SIGNATURE, new RollbackMessageEncoder());
+
+ result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder());
+ return result;
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v52/BoltProtocolV52.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v52/BoltProtocolV52.java
new file mode 100644
index 0000000000..11b47f5d18
--- /dev/null
+++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v52/BoltProtocolV52.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal.messaging.v52;
+
+import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher;
+
+import io.netty.channel.ChannelPromise;
+import java.util.Collections;
+import org.neo4j.driver.AuthToken;
+import org.neo4j.driver.NotificationConfig;
+import org.neo4j.driver.exceptions.Neo4jException;
+import org.neo4j.driver.internal.cluster.RoutingContext;
+import org.neo4j.driver.internal.handlers.HelloResponseHandler;
+import org.neo4j.driver.internal.handlers.LogonResponseHandler;
+import org.neo4j.driver.internal.messaging.BoltProtocol;
+import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
+import org.neo4j.driver.internal.messaging.request.HelloMessage;
+import org.neo4j.driver.internal.messaging.request.LogonMessage;
+import org.neo4j.driver.internal.messaging.v51.BoltProtocolV51;
+import org.neo4j.driver.internal.security.InternalAuthToken;
+
+public class BoltProtocolV52 extends BoltProtocolV51 {
+ public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(5, 2);
+ public static final BoltProtocol INSTANCE = new BoltProtocolV52();
+
+ @Override
+ public void initializeChannel(
+ String userAgent,
+ AuthToken authToken,
+ RoutingContext routingContext,
+ ChannelPromise channelInitializedPromise,
+ NotificationConfig notificationConfig) {
+ var channel = channelInitializedPromise.channel();
+ HelloMessage message;
+
+ if (routingContext.isServerRoutingEnabled()) {
+ message = new HelloMessage(
+ userAgent, Collections.emptyMap(), routingContext.toMap(), false, notificationConfig);
+ } else {
+ message = new HelloMessage(userAgent, Collections.emptyMap(), null, false, notificationConfig);
+ }
+
+ messageDispatcher(channel).enqueue(new HelloResponseHandler(channel.voidPromise()));
+ messageDispatcher(channel).enqueue(new LogonResponseHandler(channelInitializedPromise));
+ channel.write(message, channel.voidPromise());
+ channel.writeAndFlush(new LogonMessage(((InternalAuthToken) authToken).toMap()));
+ }
+
+ @Override
+ protected Neo4jException verifyNotificationConfigSupported(NotificationConfig notificationConfig) {
+ return null;
+ }
+
+ @Override
+ public BoltProtocolVersion version() {
+ return VERSION;
+ }
+}
diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java
index a1f9082eef..17feb6e70d 100644
--- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java
+++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java
@@ -20,46 +20,66 @@
import static org.neo4j.driver.internal.value.NullValue.NULL;
+import java.util.Optional;
import java.util.function.Function;
+import org.neo4j.driver.NotificationCategory;
+import org.neo4j.driver.NotificationSeverity;
import org.neo4j.driver.Value;
+import org.neo4j.driver.internal.InternalNotificationCategory;
+import org.neo4j.driver.internal.InternalNotificationSeverity;
import org.neo4j.driver.summary.InputPosition;
import org.neo4j.driver.summary.Notification;
public class InternalNotification implements Notification {
- public static final Function VALUE_TO_NOTIFICATION = new Function() {
- @Override
- public Notification apply(Value value) {
- String code = value.get("code").asString();
- String title = value.get("title").asString();
- String description = value.get("description").asString();
- String severity =
- value.containsKey("severity") ? value.get("severity").asString() : "N/A";
-
- Value posValue = value.get("position");
- InputPosition position = null;
- if (posValue != NULL) {
- position = new InternalInputPosition(
- posValue.get("offset").asInt(),
- posValue.get("line").asInt(),
- posValue.get("column").asInt());
- }
-
- return new InternalNotification(code, title, description, severity, position);
+ public static final Function VALUE_TO_NOTIFICATION = value -> {
+ String code = value.get("code").asString();
+ String title = value.get("title").asString();
+ String description = value.get("description").asString();
+ var rawSeverityLevel =
+ value.containsKey("severity") ? value.get("severity").asString() : null;
+ var severityLevel =
+ InternalNotificationSeverity.valueOf(rawSeverityLevel).orElse(null);
+ var rawCategory = value.containsKey("category") ? value.get("category").asString() : null;
+ var category = InternalNotificationCategory.valueOf(rawCategory).orElse(null);
+
+ Value posValue = value.get("position");
+ InputPosition position = null;
+ if (posValue != NULL) {
+ position = new InternalInputPosition(
+ posValue.get("offset").asInt(),
+ posValue.get("line").asInt(),
+ posValue.get("column").asInt());
}
+
+ return new InternalNotification(
+ code, title, description, severityLevel, rawSeverityLevel, category, rawCategory, position);
};
private final String code;
private final String title;
private final String description;
- private final String severity;
+ private final NotificationSeverity severityLevel;
+ private final String rawSeverityLevel;
+ private final NotificationCategory category;
+ private final String rawCategory;
private final InputPosition position;
public InternalNotification(
- String code, String title, String description, String severity, InputPosition position) {
+ String code,
+ String title,
+ String description,
+ NotificationSeverity severityLevel,
+ String rawSeverityLevel,
+ NotificationCategory category,
+ String rawCategory,
+ InputPosition position) {
this.code = code;
this.title = title;
this.description = description;
- this.severity = severity;
+ this.severityLevel = severityLevel;
+ this.rawSeverityLevel = rawSeverityLevel;
+ this.category = category;
+ this.rawCategory = rawCategory;
this.position = position;
}
@@ -84,13 +104,30 @@ public InputPosition position() {
}
@Override
- public String severity() {
- return severity;
+ public Optional severityLevel() {
+ return Optional.ofNullable(severityLevel);
+ }
+
+ @Override
+ public Optional rawSeverityLevel() {
+ return Optional.ofNullable(rawSeverityLevel);
+ }
+
+ @Override
+ public Optional category() {
+ return Optional.ofNullable(category);
+ }
+
+ @Override
+ public Optional rawCategory() {
+ return Optional.ofNullable(rawCategory);
}
@Override
public String toString() {
- String info = "code=" + code + ", title=" + title + ", description=" + description + ", severity=" + severity;
+ var info = "code=" + code + ", title=" + title + ", description=" + description + ", severityLevel="
+ + severityLevel + ", rawSeverityLevel=" + rawSeverityLevel + ", category=" + category + ", rawCategory="
+ + rawCategory;
return position == null ? info : info + ", position={" + position + "}";
}
}
diff --git a/driver/src/main/java/org/neo4j/driver/summary/Notification.java b/driver/src/main/java/org/neo4j/driver/summary/Notification.java
index df12784bb5..cba26c8489 100644
--- a/driver/src/main/java/org/neo4j/driver/summary/Notification.java
+++ b/driver/src/main/java/org/neo4j/driver/summary/Notification.java
@@ -18,11 +18,14 @@
*/
package org.neo4j.driver.summary;
+import java.util.Optional;
+import org.neo4j.driver.NotificationCategory;
+import org.neo4j.driver.NotificationSeverity;
import org.neo4j.driver.util.Immutable;
/**
* Representation for notifications found when executing a query.
- *
+ *
* A notification can be visualized in a client pinpointing problems or other information about the query.
* @since 1.0
*/
@@ -58,7 +61,51 @@ public interface Notification {
/**
* The severity level of the notification.
*
+ * @deprecated superseded by {@link #severityLevel()} and {@link #rawSeverityLevel()}
+ * @return the severity level of the notification
+ */
+ @Deprecated
+ default String severity() {
+ return rawSeverityLevel().orElse("N/A");
+ }
+
+ /**
+ * Returns the severity level of the notification.
+ *
* @return the severity level of the notification
+ * @since 5.7
+ */
+ default Optional severityLevel() {
+ return Optional.empty();
+ }
+
+ /**
+ * Returns the raw severity level of the notification as a String returned by the server.
+ *
+ * @return the severity level of the notification
+ * @since 5.7
+ */
+ default Optional rawSeverityLevel() {
+ return Optional.empty();
+ }
+
+ /**
+ * Returns the category of the notification.
+ *
+ * @return the category of the notification
+ * @since 5.7
+ */
+ default Optional category() {
+ return Optional.empty();
+ }
+
+ /**
+ * Returns the raw category of the notification as a String returned by the server.
+ *
+ * @return the category of the notification
+ * @since 5.7
*/
- String severity();
+ default Optional rawCategory() {
+ return Optional.empty();
+ }
}
diff --git a/driver/src/test/java/org/neo4j/driver/ConfigTest.java b/driver/src/test/java/org/neo4j/driver/ConfigTest.java
index 098854f655..c105cce4c5 100644
--- a/driver/src/test/java/org/neo4j/driver/ConfigTest.java
+++ b/driver/src/test/java/org/neo4j/driver/ConfigTest.java
@@ -35,6 +35,7 @@
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.junit.jupiter.api.Nested;
@@ -463,6 +464,10 @@ void shouldSerialize() throws Exception {
.withRoutingTablePurgeDelay(50000, TimeUnit.MILLISECONDS)
.withLeakedSessionsLogging()
.withMetricsAdapter(MetricsAdapter.MICROMETER)
+ .withNotificationConfig(NotificationConfig.defaultConfig()
+ .enableMinimumSeverity(NotificationSeverity.WARNING)
+ .disableCategories(
+ Set.of(NotificationCategory.UNSUPPORTED, NotificationCategory.UNRECOGNIZED)))
.build();
Config verify = TestUtil.serializeAndReadBack(config, Config.class);
@@ -492,6 +497,12 @@ void shouldSerialize() throws Exception {
assertEquals(config.metricsAdapter(), verify.metricsAdapter());
assertEquals(config.maxTransactionRetryTimeMillis(), verify.maxTransactionRetryTimeMillis());
assertEquals(config.logLeakedSessions(), verify.logLeakedSessions());
+ assertEquals(
+ NotificationConfig.defaultConfig()
+ .enableMinimumSeverity(NotificationSeverity.WARNING)
+ .disableCategories(
+ Set.of(NotificationCategory.UNSUPPORTED, NotificationCategory.UNRECOGNIZED)),
+ config.notificationConfig());
}
@Test
diff --git a/driver/src/test/java/org/neo4j/driver/ParametersTest.java b/driver/src/test/java/org/neo4j/driver/ParametersTest.java
index 9f8344670c..15de822025 100644
--- a/driver/src/test/java/org/neo4j/driver/ParametersTest.java
+++ b/driver/src/test/java/org/neo4j/driver/ParametersTest.java
@@ -111,7 +111,8 @@ private Session mockedSession() {
null,
UNLIMITED_FETCH_SIZE,
DEV_NULL_LOGGING,
- mock(BookmarkManager.class));
+ mock(BookmarkManager.class),
+ null);
return new InternalSession(session);
}
}
diff --git a/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java b/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java
index 69205f00a4..687a72cbff 100644
--- a/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java
+++ b/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java
@@ -184,6 +184,9 @@ void shouldSerialize() throws Exception {
.withFetchSize(54321L)
.withDatabase("testing")
.withImpersonatedUser("impersonator")
+ .withNotificationConfig(NotificationConfig.defaultConfig()
+ .enableMinimumSeverity(NotificationSeverity.WARNING)
+ .disableCategories(Set.of(NotificationCategory.UNSUPPORTED, NotificationCategory.UNRECOGNIZED)))
.build();
SessionConfig verify = TestUtil.serializeAndReadBack(config, SessionConfig.class);
@@ -200,5 +203,10 @@ void shouldSerialize() throws Exception {
assertEquals(config.fetchSize(), verify.fetchSize());
assertEquals(config.database(), verify.database());
assertEquals(config.impersonatedUser(), verify.impersonatedUser());
+ assertEquals(
+ NotificationConfig.defaultConfig()
+ .enableMinimumSeverity(NotificationSeverity.WARNING)
+ .disableCategories(Set.of(NotificationCategory.UNSUPPORTED, NotificationCategory.UNRECOGNIZED)),
+ config.notificationConfig());
}
}
diff --git a/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java b/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java
index e99e963a84..6073114a30 100644
--- a/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java
+++ b/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java
@@ -218,7 +218,8 @@ private ChannelConnectorImpl newConnector(
DEV_NULL_LOGGING,
new FakeClock(),
RoutingContext.EMPTY,
- DefaultDomainNameResolver.getInstance());
+ DefaultDomainNameResolver.getInstance(),
+ null);
}
private static SecurityPlan trustAllCertificates() throws GeneralSecurityException {
diff --git a/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java b/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java
index e10bf49f90..4fce571661 100644
--- a/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java
+++ b/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java
@@ -236,6 +236,7 @@ void shouldContainProfile() {
}
@Test
+ @SuppressWarnings("deprecation")
void shouldContainNotifications() {
// When
ResultSummary summary =
@@ -250,6 +251,8 @@ void shouldContainNotifications() {
assertThat(notification.title(), notNullValue());
assertThat(notification.description(), notNullValue());
assertThat(notification.severity(), notNullValue());
+ assertThat(notification.severityLevel(), notNullValue());
+ assertThat(notification.rawSeverityLevel(), notNullValue());
assertThat(notification.position(), notNullValue());
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalNotificationSeverityTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalNotificationSeverityTest.java
new file mode 100644
index 0000000000..2c6862d8c7
--- /dev/null
+++ b/driver/src/test/java/org/neo4j/driver/internal/InternalNotificationSeverityTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package org.neo4j.driver.internal;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.neo4j.driver.NotificationSeverity;
+
+class InternalNotificationSeverityTest {
+ @Test
+ void shouldSortByLevel() {
+ // GIVEN
+ var list = new java.util.ArrayList<>(List.of(
+ NotificationSeverity.WARNING, InternalNotificationSeverity.OFF, NotificationSeverity.INFORMATION));
+
+ // WHEN
+ Collections.sort(list);
+
+ // THEN
+ assertEquals(
+ List.of(
+ NotificationSeverity.INFORMATION,
+ NotificationSeverity.WARNING,
+ InternalNotificationSeverity.OFF),
+ list);
+ }
+}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java
index a6b1379fe9..1606047906 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java
@@ -101,7 +101,8 @@ private static LeakLoggingNetworkSession newSession(Logging logging, boolean ope
null,
FetchSizeUtil.UNLIMITED_FETCH_SIZE,
logging,
- mock(BookmarkManager.class));
+ mock(BookmarkManager.class),
+ null);
}
private static ConnectionProvider connectionProviderMock(boolean openConnection) {
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java
index 3750126bd2..06bcfcc393 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java
@@ -172,7 +172,7 @@ void shouldBeClosedWhenMarkedTerminatedAndClosed() {
void shouldReleaseConnectionWhenBeginFails() {
RuntimeException error = new RuntimeException("Wrong bookmark!");
Connection connection = connectionWithBegin(handler -> handler.onFailure(error));
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
Set bookmarks = Collections.singleton(InternalBookmark.parse("SomeBookmark"));
TransactionConfig txConfig = TransactionConfig.empty();
@@ -187,7 +187,7 @@ void shouldReleaseConnectionWhenBeginFails() {
@Test
void shouldNotReleaseConnectionWhenBeginSucceeds() {
Connection connection = connectionWithBegin(handler -> handler.onSuccess(emptyMap()));
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
Set bookmarks = Collections.singleton(InternalBookmark.parse("SomeBookmark"));
TransactionConfig txConfig = TransactionConfig.empty();
@@ -200,7 +200,7 @@ void shouldNotReleaseConnectionWhenBeginSucceeds() {
@Test
void shouldReleaseConnectionWhenTerminatedAndCommitted() {
Connection connection = connectionMock();
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
tx.markTerminated(null);
@@ -216,7 +216,7 @@ void shouldNotCreateCircularExceptionWhenTerminationCauseEqualsToCursorFailure()
ClientException terminationCause = new ClientException("Custom exception");
ResultCursorsHolder resultCursorsHolder = mockResultCursorWith(terminationCause);
UnmanagedTransaction tx =
- new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, resultCursorsHolder);
+ new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, resultCursorsHolder, null);
tx.markTerminated(terminationCause);
@@ -231,7 +231,7 @@ void shouldNotCreateCircularExceptionWhenTerminationCauseDifferentFromCursorFail
ClientException terminationCause = new ClientException("Custom exception");
ResultCursorsHolder resultCursorsHolder = mockResultCursorWith(new ClientException("Cursor error"));
UnmanagedTransaction tx =
- new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, resultCursorsHolder);
+ new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, resultCursorsHolder, null);
tx.markTerminated(terminationCause);
@@ -247,7 +247,7 @@ void shouldNotCreateCircularExceptionWhenTerminationCauseDifferentFromCursorFail
void shouldNotCreateCircularExceptionWhenTerminatedWithoutFailure() {
Connection connection = connectionMock();
ClientException terminationCause = new ClientException("Custom exception");
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
tx.markTerminated(terminationCause);
@@ -260,7 +260,7 @@ void shouldNotCreateCircularExceptionWhenTerminatedWithoutFailure() {
@Test
void shouldReleaseConnectionWhenTerminatedAndRolledBack() {
Connection connection = connectionMock();
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
tx.markTerminated(null);
await(tx.rollbackAsync());
@@ -271,7 +271,7 @@ void shouldReleaseConnectionWhenTerminatedAndRolledBack() {
@Test
void shouldReleaseConnectionWhenClose() throws Throwable {
Connection connection = connectionMock();
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
await(tx.closeAsync());
@@ -282,7 +282,7 @@ void shouldReleaseConnectionWhenClose() throws Throwable {
void shouldReleaseConnectionOnConnectionAuthorizationExpiredExceptionFailure() {
AuthorizationExpiredException exception = new AuthorizationExpiredException("code", "message");
Connection connection = connectionWithBegin(handler -> handler.onFailure(exception));
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
Set bookmarks = Collections.singleton(InternalBookmark.parse("SomeBookmark"));
TransactionConfig txConfig = TransactionConfig.empty();
@@ -298,7 +298,7 @@ void shouldReleaseConnectionOnConnectionAuthorizationExpiredExceptionFailure() {
void shouldReleaseConnectionOnConnectionReadTimeoutExceptionFailure() {
Connection connection =
connectionWithBegin(handler -> handler.onFailure(ConnectionReadTimeoutException.INSTANCE));
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
Set bookmarks = Collections.singleton(InternalBookmark.parse("SomeBookmark"));
TransactionConfig txConfig = TransactionConfig.empty();
@@ -328,7 +328,7 @@ void shouldReturnExistingStageOnSimilarCompletingAction(
given(connection.protocol()).willReturn(protocol);
given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection))
.willReturn(new CompletableFuture<>());
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
CompletionStage initialStage =
mapTransactionAction(initialAction, tx).get();
@@ -370,7 +370,7 @@ void shouldReturnFailingStageOnConflictingCompletingAction(
given(connection.protocol()).willReturn(protocol);
given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection))
.willReturn(protocolActionCompleted ? completedFuture(null) : new CompletableFuture<>());
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
CompletionStage originalActionStage =
mapTransactionAction(initialAction, tx).get();
@@ -413,7 +413,7 @@ void shouldReturnCompletedWithNullStageOnClosingInactiveTransactionExceptCommitt
given(connection.protocol()).willReturn(protocol);
given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection))
.willReturn(completedFuture(null));
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
CompletionStage originalActionStage =
mapTransactionAction(originalAction, tx).get();
@@ -461,7 +461,7 @@ private static UnmanagedTransaction beginTx(Connection connection) {
}
private static UnmanagedTransaction beginTx(Connection connection, Set initialBookmarks) {
- UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE);
+ UnmanagedTransaction tx = new UnmanagedTransaction(connection, (ignored) -> {}, UNLIMITED_FETCH_SIZE, null);
return await(tx.beginAsync(initialBookmarks, TransactionConfig.empty(), null));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java
index a9dedc3676..3736d7d743 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java
@@ -33,7 +33,7 @@
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
-import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
+import org.neo4j.driver.internal.messaging.v52.BoltProtocolV52;
class BoltProtocolUtilTest {
@Test
@@ -41,7 +41,7 @@ void shouldReturnHandshakeBuf() {
assertByteBufContains(
handshakeBuf(),
BOLT_MAGIC_PREAMBLE,
- BoltProtocolV5.VERSION.toInt(),
+ (2 << 16) | BoltProtocolV52.VERSION.toInt(),
(2 << 16) | BoltProtocolV44.VERSION.toInt(),
BoltProtocolV41.VERSION.toInt(),
BoltProtocolV3.VERSION.toInt());
@@ -49,7 +49,7 @@ void shouldReturnHandshakeBuf() {
@Test
void shouldReturnHandshakeString() {
- assertEquals("[0x6060b017, 5, 132100, 260, 3]", handshakeString());
+ assertEquals("[0x6060b017, 131589, 132100, 260, 3]", handshakeString());
}
@Test
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java
index 01775ec7cd..934b7c96c9 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java
@@ -59,7 +59,7 @@ void tearDown() {
void shouldFailConnectionInitializedPromiseWhenHandshakeFails() {
ChannelPromise channelInitializedPromise = channel.newPromise();
HandshakeCompletedListener listener = new HandshakeCompletedListener(
- "user-agent", authToken(), RoutingContext.EMPTY, channelInitializedPromise);
+ "user-agent", authToken(), RoutingContext.EMPTY, channelInitializedPromise, null);
ChannelPromise handshakeCompletedPromise = channel.newPromise();
IOException cause = new IOException("Bad handshake");
@@ -75,7 +75,7 @@ void shouldFailConnectionInitializedPromiseWhenHandshakeFails() {
void shouldWriteInitializationMessageInBoltV3WhenHandshakeCompleted() {
testWritingOfInitializationMessage(
BoltProtocolV3.VERSION,
- new HelloMessage(USER_AGENT, authToken().toMap(), Collections.emptyMap(), false),
+ new HelloMessage(USER_AGENT, authToken().toMap(), Collections.emptyMap(), false, null),
HelloResponseHandler.class);
}
@@ -89,7 +89,7 @@ private void testWritingOfInitializationMessage(
ChannelPromise channelInitializedPromise = channel.newPromise();
HandshakeCompletedListener listener = new HandshakeCompletedListener(
- USER_AGENT, authToken(), RoutingContext.EMPTY, channelInitializedPromise);
+ USER_AGENT, authToken(), RoutingContext.EMPTY, channelInitializedPromise, null);
ChannelPromise handshakeCompletedPromise = channel.newPromise();
handshakeCompletedPromise.setSuccess();
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java
index 139781d742..09e8173bf1 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java
@@ -141,7 +141,8 @@ private ConnectionPoolImpl newPool() throws Exception {
DEV_NULL_LOGGING,
clock,
RoutingContext.EMPTY,
- DefaultDomainNameResolver.getInstance());
+ DefaultDomainNameResolver.getInstance(),
+ null);
PoolSettings poolSettings = newSettings();
Bootstrap bootstrap = BootstrapFactory.newBootstrap(1);
return new ConnectionPoolImpl(
diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java
index e9f66227a5..2f83714237 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java
@@ -174,7 +174,8 @@ private NettyChannelPool newPool(AuthToken authToken, int maxConnections) {
DEV_NULL_LOGGING,
new FakeClock(),
RoutingContext.EMPTY,
- DefaultDomainNameResolver.getInstance());
+ DefaultDomainNameResolver.getInstance(),
+ null);
return new NettyChannelPool(
neo4j.address(), connector, bootstrap, poolHandler, ChannelHealthChecker.ACTIVE, 1_000, maxConnections);
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java
index 490fa16d64..e216918610 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java
@@ -62,7 +62,8 @@ void shouldEncodeBeginMessage(AccessMode mode, String impersonatedUser, String t
Duration txTimeout = Duration.ofSeconds(1);
encoder.encode(
- new BeginMessage(bookmarks, txTimeout, txMetadata, mode, defaultDatabase(), impersonatedUser, txType),
+ new BeginMessage(
+ bookmarks, txTimeout, txMetadata, mode, defaultDatabase(), impersonatedUser, txType, null),
packer);
InOrder order = inOrder(packer);
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java
index 2651f62e5b..aa2c169492 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java
@@ -42,7 +42,7 @@ void shouldEncodeHelloMessage() throws Exception {
authToken.put("username", value("bob"));
authToken.put("password", value("secret"));
- encoder.encode(new HelloMessage("MyDriver", authToken, null, false), packer);
+ encoder.encode(new HelloMessage("MyDriver", authToken, null, false, null), packer);
InOrder order = inOrder(packer);
order.verify(packer).packStructHeader(1, HelloMessage.SIGNATURE);
@@ -61,7 +61,7 @@ void shouldEncodeHelloMessageWithRoutingContext() throws Exception {
Map routingContext = new HashMap<>();
routingContext.put("policy", "eu-fast");
- encoder.encode(new HelloMessage("MyDriver", authToken, routingContext, false), packer);
+ encoder.encode(new HelloMessage("MyDriver", authToken, routingContext, false, null), packer);
InOrder order = inOrder(packer);
order.verify(packer).packStructHeader(1, HelloMessage.SIGNATURE);
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java
index 76629dfc22..f200e4cfbc 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java
@@ -66,7 +66,8 @@ void shouldEncodeRunWithMetadataMessage(AccessMode mode) throws Exception {
Query query = new Query("RETURN $answer", value(params));
encoder.encode(
- autoCommitTxRunMessage(query, txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, null), packer);
+ autoCommitTxRunMessage(query, txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, null, null),
+ packer);
InOrder order = inOrder(packer);
order.verify(packer).packStructHeader(3, RunWithMetadataMessage.SIGNATURE);
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java
index bfb1dae179..f099aad8c4 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java
@@ -39,7 +39,7 @@ void shouldHaveCorrectMetadata() {
authToken.put("user", value("Alice"));
authToken.put("credentials", value("SecretPassword"));
- HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap(), false);
+ HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap(), false, null);
Map expectedMetadata = new HashMap<>(authToken);
expectedMetadata.put("user_agent", value("MyDriver/1.0.2"));
@@ -57,7 +57,7 @@ void shouldHaveCorrectRoutingContext() {
routingContext.put("region", "China");
routingContext.put("speed", "Slow");
- HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, routingContext, false);
+ HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, routingContext, false, null);
Map expectedMetadata = new HashMap<>(authToken);
expectedMetadata.put("user_agent", value("MyDriver/1.0.2"));
@@ -71,7 +71,7 @@ void shouldNotExposeCredentialsInToString() {
authToken.put(PRINCIPAL_KEY, value("Alice"));
authToken.put(CREDENTIALS_KEY, value("SecretPassword"));
- HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap(), false);
+ HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap(), false, null);
assertThat(message.toString(), not(containsString("SecretPassword")));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java
index 8cf2fce601..1257474a8d 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java
@@ -60,7 +60,7 @@ void shouldHaveCorrectMetadata(AccessMode mode) {
Duration txTimeout = Duration.ofSeconds(7);
Map metadata =
- buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, null, null);
+ buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmarks, null, null, null);
Map expectedMetadata = new HashMap<>();
expectedMetadata.put(
@@ -88,7 +88,7 @@ void shouldHaveCorrectMetadataForDatabaseName(String databaseName) {
Duration txTimeout = Duration.ofSeconds(7);
Map metadata =
- buildMetadata(txTimeout, txMetadata, database(databaseName), WRITE, bookmarks, null, null);
+ buildMetadata(txTimeout, txMetadata, database(databaseName), WRITE, bookmarks, null, null, null);
Map expectedMetadata = new HashMap<>();
expectedMetadata.put(
@@ -103,7 +103,7 @@ void shouldHaveCorrectMetadataForDatabaseName(String databaseName) {
@Test
void shouldNotHaveMetadataForDatabaseNameWhenIsNull() {
Map metadata =
- buildMetadata(null, null, defaultDatabase(), WRITE, Collections.emptySet(), null, null);
+ buildMetadata(null, null, defaultDatabase(), WRITE, Collections.emptySet(), null, null, null);
assertTrue(metadata.isEmpty());
}
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java
index b9971c2495..a434897ac6 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java
@@ -136,7 +136,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -166,7 +166,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -184,7 +184,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -194,6 +194,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -204,12 +205,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -218,11 +220,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -232,11 +236,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -342,7 +346,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldNotSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
ClientException e = assertThrows(ClientException.class, () -> await(txStage));
assertThat(e.getMessage(), startsWith("Database name parameter for selecting database is not supported"));
@@ -358,7 +362,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
assertThat(e.getMessage(), startsWith("Database name parameter for selecting database is not supported"));
}
@@ -373,10 +378,11 @@ protected void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
} else {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
e = assertThrows(ClientException.class, () -> await(txStage));
}
@@ -424,7 +430,7 @@ protected void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionCon
CompletionStage cursorStage;
if (autoCommitTx) {
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -452,7 +458,7 @@ protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
assertFalse(cursorFuture.isDone());
@@ -475,7 +481,7 @@ protected void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
assertFalse(cursorFuture.isDone());
@@ -507,7 +513,7 @@ private static ResponseHandlers verifyRunInvoked(
RunWithMetadataMessage expectedMessage;
if (session) {
expectedMessage = RunWithMetadataMessage.autoCommitTxRunMessage(
- QUERY, config, defaultDatabase(), mode, bookmarks, null);
+ QUERY, config, defaultDatabase(), mode, bookmarks, null, null);
} else {
expectedMessage = RunWithMetadataMessage.unmanagedTxRunMessage(QUERY);
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java
index 7b09069219..1faaebece0 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java
@@ -100,7 +100,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -109,6 +110,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -117,6 +119,7 @@ protected Stream supportedMessages() {
WRITE,
defaultDatabase(),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -127,6 +130,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -135,6 +139,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
PULL_ALL,
@@ -149,6 +154,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -157,6 +163,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java
index 197de1e191..e6701924b7 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java
@@ -131,7 +131,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -161,7 +161,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -179,7 +179,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -189,6 +189,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -199,12 +200,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -213,11 +215,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -227,11 +231,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -337,7 +341,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
assertDoesNotThrow(() -> await(txStage));
}
@@ -350,7 +354,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
}
private BoltProtocol createProtocol() {
@@ -373,7 +378,7 @@ protected void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -400,7 +405,7 @@ protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -457,7 +462,7 @@ protected void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionCon
CompletionStage cursorStage;
if (autoCommitTx) {
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -487,15 +492,16 @@ protected void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE);
+ UNLIMITED_FETCH_SIZE,
+ null);
CompletionStage resultStage = factory.asyncResult();
ResponseHandler runHandler = verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
runHandler.onSuccess(emptyMap());
await(resultStage);
} else {
- CompletionStage txStage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ CompletionStage txStage = protocol.beginTransaction(
+ connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
await(txStage);
verifyBeginInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -513,7 +519,7 @@ private ResponseHandler verifySessionRunInvoked(
AccessMode mode,
DatabaseName databaseName) {
RunWithMetadataMessage runMessage =
- RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null);
+ RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null, null);
return verifyRunInvoked(connection, runMessage);
}
@@ -537,7 +543,7 @@ private void verifyBeginInvoked(
AccessMode mode,
DatabaseName databaseName) {
ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class);
- BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null);
+ BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null, null);
verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture());
assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java
index 00e1d772dc..c355cd68d4 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java
@@ -108,7 +108,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -117,6 +118,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -125,6 +127,7 @@ protected Stream supportedMessages() {
WRITE,
database("foo"),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -136,6 +139,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -144,6 +148,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
@@ -155,6 +160,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -163,6 +169,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java
index 0840ae0bd7..0bff6bdfa2 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java
@@ -135,7 +135,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -165,7 +165,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -183,7 +183,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -193,6 +193,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -203,12 +204,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -217,11 +219,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -231,11 +235,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -341,7 +345,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
assertDoesNotThrow(() -> await(txStage));
}
@@ -354,7 +358,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
}
private Class extends MessageFormat> expectedMessageFormatType() {
@@ -369,7 +374,7 @@ private void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -396,7 +401,7 @@ private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -452,7 +457,7 @@ private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfi
CompletionStage cursorStage;
if (autoCommitTx) {
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -480,7 +485,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE);
+ UNLIMITED_FETCH_SIZE,
+ null);
CompletionStage resultStage = factory.asyncResult();
ResponseHandler runHandler = verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -489,8 +495,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
} else {
- CompletionStage txStage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ CompletionStage txStage = protocol.beginTransaction(
+ connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
await(txStage);
verifyBeginInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -508,7 +514,7 @@ private ResponseHandler verifySessionRunInvoked(
AccessMode mode,
DatabaseName databaseName) {
RunWithMetadataMessage runMessage =
- RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null);
+ RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null, null);
return verifyRunInvoked(connection, runMessage);
}
@@ -532,7 +538,7 @@ private void verifyBeginInvoked(
AccessMode mode,
DatabaseName databaseName) {
ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class);
- BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null);
+ BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null, null);
verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture());
assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java
index d828091fcf..8f740825f5 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java
@@ -107,7 +107,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -116,6 +117,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -124,6 +126,7 @@ protected Stream supportedMessages() {
WRITE,
database("foo"),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -135,6 +138,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -143,6 +147,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
@@ -154,6 +159,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -162,6 +168,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java
index 257bc607c9..2ad341ba4b 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java
@@ -135,7 +135,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -165,7 +165,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -183,7 +183,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -193,6 +193,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -203,12 +204,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -217,11 +219,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -231,11 +235,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -341,7 +345,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
assertDoesNotThrow(() -> await(txStage));
}
@@ -354,7 +358,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
}
private Class extends MessageFormat> expectedMessageFormatType() {
@@ -369,7 +374,7 @@ private void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -395,7 +400,7 @@ private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -451,7 +456,7 @@ private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfi
CompletionStage cursorStage;
if (autoCommitTx) {
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -481,7 +486,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE);
+ UNLIMITED_FETCH_SIZE,
+ null);
CompletionStage resultStage = factory.asyncResult();
ResponseHandler runHandler = verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -490,8 +496,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
} else {
- CompletionStage txStage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ CompletionStage txStage = protocol.beginTransaction(
+ connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
await(txStage);
verifyBeginInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -509,7 +515,7 @@ private ResponseHandler verifySessionRunInvoked(
AccessMode mode,
DatabaseName databaseName) {
RunWithMetadataMessage runMessage =
- RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null);
+ RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null, null);
return verifyRunInvoked(connection, runMessage);
}
@@ -533,7 +539,7 @@ private void verifyBeginInvoked(
AccessMode mode,
DatabaseName databaseName) {
ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class);
- BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null);
+ BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null, null);
verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture());
assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java
index 7e77ca4553..aca14b8f9c 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java
@@ -107,7 +107,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -116,6 +117,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -124,6 +126,7 @@ protected Stream supportedMessages() {
WRITE,
database("foo"),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -135,6 +138,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -143,6 +147,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
@@ -154,6 +159,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -162,6 +168,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java
index e3cab020a8..701ca503e9 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java
@@ -134,7 +134,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -164,7 +164,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -182,7 +182,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -192,6 +192,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -202,12 +203,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -216,11 +218,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -230,11 +234,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -340,7 +344,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
assertDoesNotThrow(() -> await(txStage));
}
@@ -353,7 +357,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
}
private Class extends MessageFormat> expectedMessageFormatType() {
@@ -368,7 +373,7 @@ private void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -395,7 +400,7 @@ private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -453,7 +458,7 @@ private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfi
@SuppressWarnings("unchecked")
Consumer bookmarkConsumer = mock(Consumer.class);
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -483,7 +488,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE);
+ UNLIMITED_FETCH_SIZE,
+ null);
CompletionStage resultStage = factory.asyncResult();
ResponseHandler runHandler = verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -492,8 +498,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
} else {
- CompletionStage txStage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ CompletionStage txStage = protocol.beginTransaction(
+ connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
await(txStage);
verifyBeginInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -511,7 +517,7 @@ private ResponseHandler verifySessionRunInvoked(
AccessMode mode,
DatabaseName databaseName) {
RunWithMetadataMessage runMessage =
- RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null);
+ RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null, null);
return verifyRunInvoked(connection, runMessage);
}
@@ -535,7 +541,7 @@ private void verifyBeginInvoked(
AccessMode mode,
DatabaseName databaseName) {
ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class);
- BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null);
+ BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null, null);
verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture());
assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java
index 8a1b5de966..0e8b2c5319 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java
@@ -112,7 +112,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -121,6 +122,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -129,6 +131,7 @@ protected Stream supportedMessages() {
WRITE,
database("foo"),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -140,6 +143,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -148,6 +152,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
@@ -159,6 +164,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -167,6 +173,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))),
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java
index 43ddea119b..6f92adcc34 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java
@@ -134,7 +134,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -164,7 +164,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -182,7 +182,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -192,6 +192,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -202,12 +203,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -216,11 +218,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -230,11 +234,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null);
+ CompletionStage stage = protocol.beginTransaction(connection, bookmarks, txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(bookmarks, txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -340,7 +344,7 @@ void databaseNameForAutoCommitTransactions() {
@Test
void shouldSupportDatabaseNameInBeginTransaction() {
CompletionStage txStage = protocol.beginTransaction(
- connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null);
+ connectionMock("foo", protocol), Collections.emptySet(), TransactionConfig.empty(), null, null);
assertDoesNotThrow(() -> await(txStage));
}
@@ -353,7 +357,8 @@ void shouldNotSupportDatabaseNameForAutoCommitTransactions() {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE));
+ UNLIMITED_FETCH_SIZE,
+ null));
}
private Class extends MessageFormat> expectedMessageFormatType() {
@@ -368,7 +373,7 @@ private void testFailedRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -395,7 +400,7 @@ private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse(
Consumer bookmarkConsumer = mock(Consumer.class);
CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction(
- connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, bookmarks, bookmarkConsumer, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult()
.toCompletableFuture();
@@ -451,7 +456,7 @@ private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfi
CompletionStage cursorStage;
if (autoCommitTx) {
cursorStage = protocol.runInAutoCommitTransaction(
- connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE)
+ connection, QUERY, initialBookmarks, (ignored) -> {}, config, UNLIMITED_FETCH_SIZE, null)
.asyncResult();
} else {
cursorStage = protocol.runInUnmanagedTransaction(
@@ -481,7 +486,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
Collections.emptySet(),
(ignored) -> {},
TransactionConfig.empty(),
- UNLIMITED_FETCH_SIZE);
+ UNLIMITED_FETCH_SIZE,
+ null);
CompletionStage resultStage = factory.asyncResult();
ResponseHandler runHandler = verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -490,8 +496,8 @@ private void testDatabaseNameSupport(boolean autoCommitTx) {
verifySessionRunInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
} else {
- CompletionStage txStage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ CompletionStage txStage = protocol.beginTransaction(
+ connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
await(txStage);
verifyBeginInvoked(
connection, Collections.emptySet(), TransactionConfig.empty(), AccessMode.WRITE, database("foo"));
@@ -509,7 +515,7 @@ private ResponseHandler verifySessionRunInvoked(
AccessMode mode,
DatabaseName databaseName) {
RunWithMetadataMessage runMessage =
- RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null);
+ RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmarks, null, null);
return verifyRunInvoked(connection, runMessage);
}
@@ -533,7 +539,7 @@ private void verifyBeginInvoked(
AccessMode mode,
DatabaseName databaseName) {
ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class);
- BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null);
+ BeginMessage beginMessage = new BeginMessage(bookmarks, config, databaseName, mode, null, null, null);
verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture());
assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class));
}
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java
index 0ac43c80fc..9734e81ea4 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java
@@ -112,7 +112,8 @@ protected Stream supportedMessages() {
"MyDriver/1.2.3",
((InternalAuthToken) basic("neo4j", "neo4j")).toMap(),
Collections.emptyMap(),
- false),
+ false,
+ null),
GOODBYE,
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -121,6 +122,7 @@ protected Stream supportedMessages() {
READ,
defaultDatabase(),
null,
+ null,
null),
new BeginMessage(
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx123")),
@@ -129,6 +131,7 @@ protected Stream supportedMessages() {
WRITE,
database("foo"),
null,
+ null,
null),
COMMIT,
ROLLBACK,
@@ -140,6 +143,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN 1"),
@@ -148,6 +152,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx1")),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN 1")),
@@ -159,6 +164,7 @@ protected Stream supportedMessages() {
defaultDatabase(),
READ,
Collections.emptySet(),
+ null,
null),
autoCommitTxRunMessage(
new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))),
@@ -167,6 +173,7 @@ protected Stream supportedMessages() {
database("foo"),
WRITE,
Collections.emptySet(),
+ null,
null),
unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))),
diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v5/BoltProtocolV5Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v5/BoltProtocolV5Test.java
index cecfcc043e..1c7836b6fd 100644
--- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v5/BoltProtocolV5Test.java
+++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v5/BoltProtocolV5Test.java
@@ -134,7 +134,7 @@ void shouldCreateMessageFormat() {
void shouldInitializeChannel() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -164,7 +164,7 @@ void shouldPrepareToCloseChannel() {
void shouldFailToInitializeChannelWhenErrorIsReceived() {
ChannelPromise promise = channel.newPromise();
- protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise);
+ protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise, null);
assertThat(channel.outboundMessages(), hasSize(1));
assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class));
@@ -182,7 +182,7 @@ void shouldBeginTransactionWithoutBookmark() {
Connection connection = connectionMock(protocol);
CompletionStage stage =
- protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null);
+ protocol.beginTransaction(connection, Collections.emptySet(), TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
@@ -192,6 +192,7 @@ void shouldBeginTransactionWithoutBookmark() {
defaultDatabase(),
WRITE,
null,
+ null,
null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
@@ -202,12 +203,13 @@ void shouldBeginTransactionWithBookmarks() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx100"));
- CompletionStage stage = protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, bookmarks, TransactionConfig.empty(), null, null);
verify(connection)
.writeAndFlush(
eq(new BeginMessage(
- bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null)),
+ bookmarks, TransactionConfig.empty(), defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -216,11 +218,13 @@ void shouldBeginTransactionWithBookmarks() {
void shouldBeginTransactionWithConfig() {
Connection connection = connectionMock(protocol);
- CompletionStage stage = protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null);
+ CompletionStage stage =
+ protocol.beginTransaction(connection, Collections.emptySet(), txConfig, null, null);
verify(connection)
.writeAndFlush(
- eq(new BeginMessage(Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null)),
+ eq(new BeginMessage(
+ Collections.emptySet(), txConfig, defaultDatabase(), WRITE, null, null, null)),
any(BeginTxResponseHandler.class));
assertNull(await(stage));
}
@@ -230,11 +234,11 @@ void shouldBeginTransactionWithBookmarksAndConfig() {
Connection connection = connectionMock(protocol);
Set bookmarks = Collections.singleton(InternalBookmark.parse("neo4j:bookmark:v1:tx4242"));
- CompletionStage