Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ability to override discoverable bolt URI
This introduces a minor overhaul of the discovery service, allowing arbitrary URLs to be published to it. That functionality is leveraged to have the enterprise edition of the server publish a `bolt+routing` URI. -- This has two elements that will make it confusing - the term "discovery", and the idea of a "public" URI for Bolt. "Discovery" in Neo could refer both to the discovery *protocol*, used by causal clustering, or to REST API Discovery, the idea that the HTTP API describes its own capabilities. This PR is exclusively about REST/HTTP discovery - it is adding a capability to the JSON document a user recieves when she does: GET http://localhost:7474 The "public" URI portion is more complex, and is the core of what this PR is mucking about in. Currently, you can find a Bolt URL to a Neo4j instance in two ways - by asking the HTTP discovery endpoint, or by asking the routing table procedure. Currently, both of these methods will give you URLs ultimately originating from the configuration of the `advertised_address` on the bolt connector. However, they serve two different purposes. The routing table is used *internally* by Bolt Drivers, providing addresses to connect to exact and specific Neo4j instances. The Discovery URL is used *externally*, as the root URL to give to a driver. By connecting via HTTP and retrieving the discovery document, tools like the browser find out the appropriate URL to pass when creating a Bolt Driver. Hence - a sensible "Advertised" URL is always a "bolt://..." URL pointing to the specific instance being configured. However, a sensible "Discoverable" URL is sometimes different - specifically, it may very reasonably be "bolt+routing://path-to-some-load-balancer".
- Loading branch information
Showing
20 changed files
with
542 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
...unity/server/src/main/java/org/neo4j/server/rest/discovery/CommunityDiscoverableURIs.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright (c) 2002-2018 "Neo4j," | ||
* Neo4j Sweden AB [http://neo4j.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.server.rest.discovery; | ||
|
||
import org.neo4j.kernel.configuration.Config; | ||
import org.neo4j.kernel.configuration.ConnectorPortRegister; | ||
import org.neo4j.server.configuration.ServerSettings; | ||
|
||
public class CommunityDiscoverableURIs | ||
{ | ||
/** | ||
* URIs exposed at the root HTTP endpoint, to help clients discover the rest of the service. | ||
*/ | ||
public static DiscoverableURIs communityDiscoverableURIs( Config config, ConnectorPortRegister portRegister ) | ||
{ | ||
DiscoverableURIs repo = new DiscoverableURIs(); | ||
repo.addRelative( "data", config.get( ServerSettings.rest_api_path ).getPath() + "/" ); | ||
repo.addRelative( "management", config.get( ServerSettings.management_api_path ).getPath() + "/" ); | ||
|
||
DiscoverableURIs | ||
.discoverableBoltUri("bolt", config, ServerSettings.bolt_discoverable_address, portRegister ) | ||
.ifPresent( uri -> repo.addAbsolute( "bolt", uri ) ); | ||
return repo; | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
community/server/src/main/java/org/neo4j/server/rest/discovery/DiscoverableURIs.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Copyright (c) 2002-2018 "Neo4j," | ||
* Neo4j Sweden AB [http://neo4j.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.server.rest.discovery; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Optional; | ||
import java.util.function.BiConsumer; | ||
|
||
import org.neo4j.graphdb.config.InvalidSettingException; | ||
import org.neo4j.graphdb.config.Setting; | ||
import org.neo4j.helpers.AdvertisedSocketAddress; | ||
import org.neo4j.helpers.collection.Pair; | ||
import org.neo4j.kernel.configuration.Config; | ||
import org.neo4j.kernel.configuration.ConnectorPortRegister; | ||
|
||
/** | ||
* Repository of URIs that the REST API publicly advertises at the root endpoint. | ||
*/ | ||
public class DiscoverableURIs | ||
{ | ||
private final Collection<Pair<String,String>> relativeUris = new ArrayList<>(); | ||
private final Collection<Pair<String,URI>> absoluteUris = new ArrayList<>(); | ||
|
||
public DiscoverableURIs addRelative( String key, String uri ) | ||
{ | ||
relativeUris.add( Pair.pair( key, uri ) ); | ||
return this; | ||
} | ||
|
||
public DiscoverableURIs addAbsolute( String key, URI uri ) | ||
{ | ||
absoluteUris.add( Pair.pair( key, uri ) ); | ||
return this; | ||
} | ||
|
||
public static Optional<URI> discoverableBoltUri( String scheme, Config config, Setting<URI> override, | ||
ConnectorPortRegister connectorPortRegister ) | ||
{ | ||
// Note that this whole function would be much cleaner to implement as a default function for the | ||
// bolt_discoverable_address setting; however the current config design makes it hard to do | ||
// "find any bolt connector", it can only do "find exactly this config key".. Something to refactor | ||
// when we refactor config API for 4.0. | ||
if ( config.isConfigured( override ) ) | ||
{ | ||
return Optional.ofNullable( config.get( override ) ); | ||
} | ||
|
||
return config.enabledBoltConnectors().stream().findFirst().map( c -> | ||
{ | ||
AdvertisedSocketAddress advertisedSocketAddress = config.get( c.advertised_address ); | ||
|
||
// If port is 0 it's been assigned a random port from the OS, list this instead | ||
if ( advertisedSocketAddress.getPort() == 0 ) | ||
{ | ||
int boltPort = connectorPortRegister.getLocalAddress( c.key() ).getPort(); | ||
return boltURI( scheme, advertisedSocketAddress.getHostname(), boltPort ); | ||
} | ||
|
||
// Use the config verbatim since it seems sane | ||
return boltURI( scheme, advertisedSocketAddress.getHostname(), advertisedSocketAddress.getPort() ); | ||
} ); | ||
} | ||
|
||
public void forEachRelativeUri( BiConsumer<String,String> consumer ) | ||
{ | ||
relativeUris.forEach( p -> consumer.accept( p.first(), p.other() ) ); | ||
} | ||
|
||
public void forEachAbsoluteUri( BiConsumer<String,URI> consumer ) | ||
{ | ||
absoluteUris.forEach( p -> consumer.accept( p.first(), p.other() ) ); | ||
} | ||
|
||
private static URI boltURI( String scheme, String host, int port ) | ||
{ | ||
try | ||
{ | ||
return new URI( scheme, null, host, port, null, null, null ); | ||
} | ||
catch ( URISyntaxException e ) | ||
{ | ||
throw new InvalidSettingException( | ||
String.format( "Unable to construct bolt discoverable URI using '%s' as hostname: " + "%s", host, | ||
e.getMessage() ), e ); | ||
} | ||
} | ||
} |
Oops, something went wrong.