Skip to content

Commit dcbc6f4

Browse files
author
Zhen
committed
Resolve dns to ip
1 parent e652e05 commit dcbc6f4

File tree

7 files changed

+158
-28
lines changed

7 files changed

+158
-28
lines changed

driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterRoutingTable.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,18 @@ public synchronized Set<BoltServerAddress> update( ClusterComposition cluster )
7575
return removed;
7676
}
7777

78+
@Override
79+
public synchronized Set<BoltServerAddress> updateRouters( Set<BoltServerAddress> address )
80+
{
81+
Set<BoltServerAddress> removed = new HashSet<>();
82+
routers.update( address, removed );
83+
return removed;
84+
}
85+
7886
@Override
7987
public synchronized void forget( BoltServerAddress address )
8088
{
81-
// Don't remove it from the set of routers, since that might mean we lose our ability to re-discover,
82-
// just remove it from the set of readers and writers, so that we don't use it for actual work without
83-
// performing discovery first.
89+
routers.remove( address );
8490
readers.remove( address );
8591
writers.remove( address );
8692
}
@@ -115,11 +121,6 @@ public void removeWriter( BoltServerAddress toRemove )
115121
writers.remove( toRemove );
116122
}
117123

118-
@Override
119-
public void removeRouter( BoltServerAddress toRemove )
120-
{
121-
routers.remove( toRemove );
122-
}
123124

124125
@Override
125126
public String toString()
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2002-2017 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.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.cluster;
20+
21+
import java.net.InetAddress;
22+
import java.net.UnknownHostException;
23+
import java.util.HashSet;
24+
import java.util.Set;
25+
26+
import org.neo4j.driver.internal.net.BoltServerAddress;
27+
import org.neo4j.driver.v1.exceptions.ServiceUnavailableException;
28+
29+
public interface DnsResolver
30+
{
31+
DnsResolver DEFAULT = new DnsResolver()
32+
{
33+
@Override
34+
public Set<BoltServerAddress> resolve( BoltServerAddress initialRouter )
35+
{
36+
try
37+
{
38+
InetAddress[] ipAddresses = InetAddress.getAllByName( initialRouter.host() );
39+
Set<BoltServerAddress> addresses = new HashSet<>( ipAddresses.length );
40+
41+
for ( int i = 0; i < ipAddresses.length; i ++ )
42+
{
43+
addresses.add( new BoltServerAddress( ipAddresses[i].getHostAddress(), initialRouter.port() ) );
44+
}
45+
46+
return addresses;
47+
48+
}
49+
catch ( UnknownHostException e )
50+
{
51+
throw new ServiceUnavailableException(
52+
"Failed to resolve URI `" + initialRouter + "` to IPs due to error: " + e.getMessage(), e );
53+
}
54+
}
55+
};
56+
57+
Set<BoltServerAddress> resolve( BoltServerAddress initialRouter );
58+
}

driver/src/main/java/org/neo4j/driver/internal/cluster/LoadBalancer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,6 @@ private static Rediscovery createRediscovery( BoltServerAddress initialRouter, R
157157
Clock clock, Logger log )
158158
{
159159
ClusterCompositionProvider clusterComposition = new GetServersProcedureClusterCompositionProvider( clock, log );
160-
return new Rediscovery( initialRouter, settings, clock, log, clusterComposition );
160+
return new Rediscovery( initialRouter, settings, clock, log, clusterComposition, DnsResolver.DEFAULT );
161161
}
162162
}

driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java

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

21+
import java.util.Set;
22+
2123
import org.neo4j.driver.internal.net.BoltServerAddress;
2224
import org.neo4j.driver.internal.spi.Connection;
2325
import org.neo4j.driver.internal.spi.ConnectionPool;
@@ -37,15 +39,17 @@ public class Rediscovery
3739
private final Clock clock;
3840
private final Logger logger;
3941
private final ClusterCompositionProvider provider;
42+
private final DnsResolver dnsResolver;
4043

4144
public Rediscovery( BoltServerAddress initialRouter, RoutingSettings settings, Clock clock, Logger logger,
42-
ClusterCompositionProvider provider )
45+
ClusterCompositionProvider provider, DnsResolver dnsResolver )
4346
{
4447
this.initialRouter = initialRouter;
4548
this.settings = settings;
4649
this.clock = clock;
4750
this.logger = logger;
4851
this.provider = provider;
52+
this.dnsResolver = dnsResolver;
4953
}
5054

5155
// Given the current routing table and connection pool, use the connection composition provider to fetch a new
@@ -76,7 +80,12 @@ public ClusterComposition lookupClusterComposition( ConnectionPool connections,
7680
private ClusterComposition lookupClusterCompositionOnKnownRouters( ConnectionPool connections,
7781
RoutingTable routingTable )
7882
{
79-
boolean triedInitialRouter = false;
83+
if( routingTable.routerSize() == 0 )
84+
{
85+
Set<BoltServerAddress> ips = dnsResolver.resolve( initialRouter );
86+
routingTable.updateRouters( ips );
87+
}
88+
8089
int size = routingTable.routerSize();
8190
for ( int i = 0; i < size; i++ )
8291
{
@@ -86,23 +95,14 @@ private ClusterComposition lookupClusterCompositionOnKnownRouters( ConnectionPoo
8695
break;
8796
}
8897

89-
if ( address.equals( initialRouter ) )
90-
{
91-
triedInitialRouter = true;
92-
}
93-
9498
ClusterComposition composition = lookupClusterCompositionOnRouter( address, connections, routingTable );
9599
if ( composition != null )
96100
{
97101
return composition;
98102
}
99103
}
100104

101-
if ( triedInitialRouter )
102-
{
103-
return null;
104-
}
105-
return lookupClusterCompositionOnRouter( initialRouter, connections, routingTable );
105+
return null;
106106
}
107107

108108
private ClusterComposition lookupClusterCompositionOnRouter( BoltServerAddress routerAddress,
@@ -122,7 +122,7 @@ private ClusterComposition lookupClusterCompositionOnRouter( BoltServerAddress r
122122
{
123123
// connection turned out to be broken
124124
logger.error( format( "Failed to connect to routing server '%s'.", routerAddress ), t );
125-
routingTable.removeRouter( routerAddress );
125+
routingTable.forget( routerAddress );
126126
return null;
127127
}
128128

driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public interface RoutingTable
2828

2929
Set<BoltServerAddress> update( ClusterComposition cluster );
3030

31+
Set<BoltServerAddress> updateRouters( Set<BoltServerAddress> address );
32+
3133
void forget( BoltServerAddress address );
3234

3335
RoundRobinAddressSet readers();
@@ -39,6 +41,4 @@ public interface RoutingTable
3941
int routerSize();
4042

4143
void removeWriter( BoltServerAddress toRemove );
42-
43-
void removeRouter( BoltServerAddress toRemove );
4444
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2002-2017 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.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.cluster;
20+
21+
import org.junit.Test;
22+
23+
import java.util.Set;
24+
25+
import org.neo4j.driver.internal.net.BoltServerAddress;
26+
27+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
28+
import static org.junit.Assert.assertThat;
29+
import static org.neo4j.driver.internal.cluster.DnsResolver.DEFAULT;
30+
31+
public class DnsResolverTest
32+
{
33+
@Test
34+
public void shouldResolveDNSToIPs()
35+
{
36+
Set<BoltServerAddress> resolve = DEFAULT.resolve( new BoltServerAddress( "google.com", 80 ) );
37+
assertThat( resolve.size(), greaterThanOrEqualTo( 1 ) );
38+
}
39+
40+
@Test
41+
public void shouldResolveLocalhostDNSToIPs()
42+
{
43+
Set<BoltServerAddress> resolve = DEFAULT.resolve( new BoltServerAddress( "127.0.0.1", 80 ) );
44+
assertThat( resolve.size(), greaterThanOrEqualTo( 1 ) );
45+
}
46+
}

driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626

2727
import java.util.ArrayList;
2828
import java.util.Collection;
29+
import java.util.HashSet;
2930
import java.util.List;
31+
import java.util.Set;
3032

3133
import org.neo4j.driver.internal.net.BoltServerAddress;
3234
import org.neo4j.driver.internal.spi.Connection;
@@ -92,7 +94,7 @@ public void shouldTryConfiguredMaxRoutingFailures() throws Exception
9294
when( mockedProvider.getClusterComposition( any( Connection.class ) ) )
9395
.thenReturn( success( INVALID_CLUSTER_COMPOSITION ) );
9496

95-
Rediscovery rediscovery = new Rediscovery( A, settings, clock, DEV_NULL_LOGGER, mockedProvider );
97+
Rediscovery rediscovery = new Rediscovery( A, settings, clock, DEV_NULL_LOGGER, mockedProvider, directMapProvider );
9698

9799
// when
98100
try
@@ -373,6 +375,17 @@ public void shouldUseInitialRouterWhenNoneOfExistingRoutersRespond()
373375

374376
RoutingTable routingTable = new TestRoutingTable( B, C );
375377

378+
// The first call will remove B, C from routing table
379+
// The second call will add A back
380+
try
381+
{
382+
rediscover( A, connections, routingTable, clusterComposition );
383+
fail( "Should error for no router" );
384+
}
385+
catch ( ServiceUnavailableException e )
386+
{
387+
assertThat( e.getMessage(), equalTo( "Could not perform discovery. No routing servers available." ) );
388+
}
376389
ClusterComposition composition = rediscover( A, connections, routingTable, clusterComposition );
377390

378391
assertEquals( VALID_CLUSTER_COMPOSITION, composition );
@@ -454,10 +467,22 @@ private static ClusterComposition rediscover( BoltServerAddress initialRouter, C
454467
Clock mockedClock = mock( Clock.class );
455468
Logger mockedLogger = mock( Logger.class );
456469

457-
Rediscovery rediscovery = new Rediscovery( initialRouter, settings, mockedClock, mockedLogger, provider );
470+
Rediscovery rediscovery = new Rediscovery( initialRouter, settings, mockedClock, mockedLogger, provider,
471+
directMapProvider );
458472
return rediscovery.lookupClusterComposition( connections, routingTable );
459473
}
460474

475+
private static DnsResolver directMapProvider = new DnsResolver()
476+
{
477+
@Override
478+
public Set<BoltServerAddress> resolve( BoltServerAddress initialRouter )
479+
{
480+
Set<BoltServerAddress> directMap = new HashSet<>( 1 );
481+
directMap.add( initialRouter );
482+
return directMap;
483+
}
484+
};
485+
461486
private static class TestRoutingTable extends ClusterRoutingTable
462487
{
463488
final List<BoltServerAddress> removedRouters = new ArrayList<>();
@@ -468,9 +493,9 @@ private static class TestRoutingTable extends ClusterRoutingTable
468493
}
469494

470495
@Override
471-
public void removeRouter( BoltServerAddress router )
496+
public void forget( BoltServerAddress router )
472497
{
473-
super.removeRouter( router );
498+
super.forget( router );
474499
removedRouters.add( router );
475500
}
476501
}

0 commit comments

Comments
 (0)