Skip to content

Commit 26aff78

Browse files
author
Zhen Li
committed
Better error message for default database routing table update
Introduced `DatabaseName` which provides a `description` method to better describe the database name. This avoid checking if database string is for "default database" everywhere in our code. It also simplifies internal logic to distinguish between database name not provided or default database name is provided.
1 parent e257197 commit 26aff78

File tree

62 files changed

+557
-305
lines changed

Some content is hidden

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

62 files changed

+557
-305
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.neo4j.driver.reactive.RxSession;
2727

2828
import static java.util.Objects.requireNonNull;
29-
import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.ABSENT_DB_NAME;
3029

3130
/**
3231
* The session configurations used to configure a session.
@@ -222,9 +221,9 @@ public Builder withDefaultAccessMode( AccessMode mode )
222221
public Builder withDatabase( String database )
223222
{
224223
requireNonNull( database, "Database name should not be null." );
225-
if ( ABSENT_DB_NAME.equals( database ) )
224+
if ( database.isEmpty() )
226225
{
227-
// Disallow users to use bolt internal value directly. To users, this is totally an illegal database name.
226+
// Empty string is an illegal database name. Fail fast on client.
228227
throw new IllegalArgumentException( String.format( "Illegal database name '%s'.", database ) );
229228
}
230229
this.database = database;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2002-2019 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import java.util.Optional;
22+
23+
public interface DatabaseName
24+
{
25+
Optional<String> databaseName();
26+
27+
String description();
28+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2002-2019 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import java.util.Objects;
22+
import java.util.Optional;
23+
24+
public final class DatabaseNameUtil
25+
{
26+
static final String DEFAULT_DATABASE_NAME = null;
27+
public static final String SYSTEM_DATABASE_NAME = "system";
28+
29+
private static final DatabaseName DEFAULT_DATABASE = new DatabaseName()
30+
{
31+
@Override
32+
public Optional<String> databaseName()
33+
{
34+
return Optional.empty();
35+
}
36+
37+
@Override
38+
public String description()
39+
{
40+
return "<default database>";
41+
}
42+
};
43+
private static final DatabaseName SYSTEM_DATABASE = new InternalDatabaseName( SYSTEM_DATABASE_NAME );
44+
45+
public static DatabaseName defaultDatabase()
46+
{
47+
return DEFAULT_DATABASE;
48+
}
49+
50+
public static DatabaseName systemDatabase()
51+
{
52+
return SYSTEM_DATABASE;
53+
}
54+
55+
public static DatabaseName database( String name )
56+
{
57+
if ( Objects.equals( name, DEFAULT_DATABASE_NAME ) )
58+
{
59+
return defaultDatabase();
60+
}
61+
else if ( Objects.equals( name, SYSTEM_DATABASE_NAME ) )
62+
{
63+
return systemDatabase();
64+
}
65+
return new InternalDatabaseName( name );
66+
}
67+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2002-2019 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import java.util.Objects;
22+
import java.util.Optional;
23+
24+
import static java.util.Objects.requireNonNull;
25+
26+
public class InternalDatabaseName implements DatabaseName
27+
{
28+
private final String databaseName;
29+
30+
InternalDatabaseName( String databaseName )
31+
{
32+
this.databaseName = requireNonNull( databaseName );
33+
}
34+
35+
@Override
36+
public Optional<String> databaseName()
37+
{
38+
return Optional.of( databaseName );
39+
}
40+
41+
@Override
42+
public String description()
43+
{
44+
return databaseName;
45+
}
46+
47+
@Override
48+
public boolean equals( Object o )
49+
{
50+
if ( this == o )
51+
{
52+
return true;
53+
}
54+
if ( o == null || getClass() != o.getClass() )
55+
{
56+
return false;
57+
}
58+
InternalDatabaseName that = (InternalDatabaseName) o;
59+
return databaseName.equals( that.databaseName );
60+
}
61+
62+
@Override
63+
public int hashCode()
64+
{
65+
return Objects.hash( databaseName );
66+
}
67+
68+
@Override
69+
public String toString()
70+
{
71+
return "InternalDatabaseName{" + "databaseName='" + databaseName + '\'' + '}';
72+
}
73+
}

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,18 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21+
import java.util.Optional;
2122
import java.util.concurrent.CompletionStage;
2223

2324
import org.neo4j.driver.AccessMode;
2425
import org.neo4j.driver.Config;
2526
import org.neo4j.driver.Logging;
2627
import org.neo4j.driver.SessionConfig;
27-
import org.neo4j.driver.internal.async.NetworkSession;
2828
import org.neo4j.driver.internal.async.LeakLoggingNetworkSession;
29+
import org.neo4j.driver.internal.async.NetworkSession;
2930
import org.neo4j.driver.internal.retry.RetryLogic;
3031
import org.neo4j.driver.internal.spi.ConnectionProvider;
3132

32-
import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.ABSENT_DB_NAME;
33-
3433
public class SessionFactoryImpl implements SessionFactory
3534
{
3635
private final ConnectionProvider connectionProvider;
@@ -50,10 +49,17 @@ public class SessionFactoryImpl implements SessionFactory
5049
public NetworkSession newInstance( SessionConfig sessionConfig )
5150
{
5251
BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( InternalBookmark.from( sessionConfig.bookmarks() ) );
53-
return createSession( connectionProvider, retryLogic, sessionConfig.database().orElse( ABSENT_DB_NAME ),
52+
return createSession( connectionProvider, retryLogic, parseDatabaseName( sessionConfig ),
5453
sessionConfig.defaultAccessMode(), bookmarkHolder, logging );
5554
}
5655

56+
private DatabaseName parseDatabaseName( SessionConfig sessionConfig )
57+
{
58+
return sessionConfig.database()
59+
.flatMap( name -> Optional.of( DatabaseNameUtil.database( name ) ) )
60+
.orElse( DatabaseNameUtil.defaultDatabase() );
61+
}
62+
5763
@Override
5864
public CompletionStage<Void> verifyConnectivity()
5965
{
@@ -78,7 +84,7 @@ public ConnectionProvider getConnectionProvider()
7884
return connectionProvider;
7985
}
8086

81-
private NetworkSession createSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, String databaseName, AccessMode mode,
87+
private NetworkSession createSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode,
8288
BookmarkHolder bookmarkHolder, Logging logging )
8389
{
8490
return leakedSessionsLoggingEnabled

driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
package org.neo4j.driver.internal.async;
2020

2121
import org.neo4j.driver.AccessMode;
22+
import org.neo4j.driver.internal.DatabaseName;
2223
import org.neo4j.driver.internal.InternalBookmark;
2324

2425
public interface ConnectionContext
2526
{
26-
String databaseName();
27+
DatabaseName databaseName();
2728

2829
AccessMode mode();
2930

driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,33 @@
1919
package org.neo4j.driver.internal.async;
2020

2121
import org.neo4j.driver.AccessMode;
22+
import org.neo4j.driver.internal.DatabaseName;
2223
import org.neo4j.driver.internal.InternalBookmark;
2324
import org.neo4j.driver.internal.spi.Connection;
2425

26+
import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase;
2527
import static org.neo4j.driver.internal.InternalBookmark.empty;
26-
import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.ABSENT_DB_NAME;
2728

2829
/**
2930
* A {@link Connection} shall fulfil this {@link ImmutableConnectionContext} when acquired from a connection provider.
3031
*/
3132
public class ImmutableConnectionContext implements ConnectionContext
3233
{
33-
private static final ConnectionContext SIMPLE = new ImmutableConnectionContext( ABSENT_DB_NAME, empty(), AccessMode.READ );
34+
private static final ConnectionContext SIMPLE = new ImmutableConnectionContext( defaultDatabase(), empty(), AccessMode.READ );
3435

35-
private final String databaseName;
36+
private final DatabaseName databaseName;
3637
private final AccessMode mode;
3738
private final InternalBookmark rediscoveryBookmark;
3839

39-
public ImmutableConnectionContext( String databaseName, InternalBookmark bookmark, AccessMode mode )
40+
public ImmutableConnectionContext( DatabaseName databaseName, InternalBookmark bookmark, AccessMode mode )
4041
{
4142
this.databaseName = databaseName;
4243
this.rediscoveryBookmark = bookmark;
4344
this.mode = mode;
4445
}
4546

4647
@Override
47-
public String databaseName()
48+
public DatabaseName databaseName()
4849
{
4950
return databaseName;
5051
}

driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.neo4j.driver.AccessMode;
2222
import org.neo4j.driver.Logging;
2323
import org.neo4j.driver.internal.BookmarkHolder;
24+
import org.neo4j.driver.internal.DatabaseName;
2425
import org.neo4j.driver.internal.retry.RetryLogic;
2526
import org.neo4j.driver.internal.spi.ConnectionProvider;
2627
import org.neo4j.driver.internal.util.Futures;
@@ -31,7 +32,7 @@ public class LeakLoggingNetworkSession extends NetworkSession
3132
{
3233
private final String stackTrace;
3334

34-
public LeakLoggingNetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, String databaseName, AccessMode mode,
35+
public LeakLoggingNetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode,
3536
BookmarkHolder bookmarkHolder, Logging logging )
3637
{
3738
super( connectionProvider, retryLogic, databaseName, mode, bookmarkHolder, logging );

driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323
import java.util.concurrent.atomic.AtomicBoolean;
2424

2525
import org.neo4j.driver.AccessMode;
26+
import org.neo4j.driver.Bookmark;
2627
import org.neo4j.driver.Logger;
2728
import org.neo4j.driver.Logging;
2829
import org.neo4j.driver.Statement;
2930
import org.neo4j.driver.TransactionConfig;
3031
import org.neo4j.driver.async.StatementResultCursor;
3132
import org.neo4j.driver.exceptions.ClientException;
32-
import org.neo4j.driver.Bookmark;
3333
import org.neo4j.driver.internal.BookmarkHolder;
34+
import org.neo4j.driver.internal.DatabaseName;
3435
import org.neo4j.driver.internal.FailableCursor;
3536
import org.neo4j.driver.internal.InternalBookmark;
3637
import org.neo4j.driver.internal.cursor.InternalStatementResultCursor;
@@ -62,7 +63,7 @@ public class NetworkSession
6263

6364
private final AtomicBoolean open = new AtomicBoolean( true );
6465

65-
public NetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, String databaseName, AccessMode mode,
66+
public NetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode,
6667
BookmarkHolder bookmarkHolder, Logging logging )
6768
{
6869
this.connectionProvider = connectionProvider;
@@ -344,17 +345,17 @@ private void ensureSessionIsOpen()
344345
/**
345346
* A {@link Connection} shall fulfil this {@link ImmutableConnectionContext} when acquired from a connection provider.
346347
*/
347-
private class NetworkSessionConnectionContext implements ConnectionContext
348+
private static class NetworkSessionConnectionContext implements ConnectionContext
348349
{
349-
private final String databaseName;
350+
private final DatabaseName databaseName;
350351
private AccessMode mode;
351352

352353
// This bookmark is only used for rediscovery.
353354
// It has to be the initial bookmark given at the creation of the session.
354355
// As only that bookmark could carry extra system bookmarks
355356
private final InternalBookmark rediscoveryBookmark;
356357

357-
private NetworkSessionConnectionContext( String databaseName, InternalBookmark bookmark )
358+
private NetworkSessionConnectionContext( DatabaseName databaseName, InternalBookmark bookmark )
358359
{
359360
this.databaseName = databaseName;
360361
this.rediscoveryBookmark = bookmark;
@@ -367,7 +368,7 @@ private ConnectionContext contextWithMode( AccessMode mode )
367368
}
368369

369370
@Override
370-
public String databaseName()
371+
public DatabaseName databaseName()
371372
{
372373
return databaseName;
373374
}

driver/src/main/java/org/neo4j/driver/internal/async/connection/DirectConnection.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.concurrent.CompletionStage;
2222

2323
import org.neo4j.driver.internal.BoltServerAddress;
24+
import org.neo4j.driver.internal.DatabaseName;
2425
import org.neo4j.driver.internal.DirectConnectionProvider;
2526
import org.neo4j.driver.internal.messaging.BoltProtocol;
2627
import org.neo4j.driver.internal.messaging.Message;
@@ -36,9 +37,9 @@ public class DirectConnection implements Connection
3637
{
3738
private final Connection delegate;
3839
private final AccessMode mode;
39-
private final String databaseName;
40+
private final DatabaseName databaseName;
4041

41-
public DirectConnection( Connection delegate, String databaseName, AccessMode mode )
42+
public DirectConnection( Connection delegate, DatabaseName databaseName, AccessMode mode )
4243
{
4344
this.delegate = delegate;
4445
this.mode = mode;
@@ -135,7 +136,7 @@ public AccessMode mode()
135136
}
136137

137138
@Override
138-
public String databaseName()
139+
public DatabaseName databaseName()
139140
{
140141
return this.databaseName;
141142
}

0 commit comments

Comments
 (0)