Merge branch 'pr/15724-gce-network-host-master'

This commit is contained in:
David Pilato 2016-07-28 16:59:18 +02:00
commit 0d2ccf0989
42 changed files with 549 additions and 291 deletions

View File

@ -108,7 +108,7 @@ public abstract class TransportClient extends AbstractClient {
final List<Closeable> resourcesToClose = new ArrayList<>();
final ThreadPool threadPool = new ThreadPool(settings);
resourcesToClose.add(() -> ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS));
final NetworkService networkService = new NetworkService(settings);
final NetworkService networkService = new NetworkService(settings, Collections.emptyList());
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
try {
final List<Setting<?>> additionalSettings = new ArrayList<>();

View File

@ -20,7 +20,6 @@
package org.elasticsearch.common.network;
import org.elasticsearch.action.support.replication.ReplicationTask;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand;
import org.elasticsearch.cluster.routing.allocation.command.AllocateReplicaAllocationCommand;
import org.elasticsearch.cluster.routing.allocation.command.AllocateStalePrimaryAllocationCommand;
@ -75,13 +74,13 @@ public class NetworkModule extends AbstractModule {
/**
* Creates a network module that custom networking classes can be plugged into.
*
* @param networkService A constructed network service object to bind.
* @param networkService A constructed network service object to bind.
* @param settings The settings for the node
* @param transportClient True if only transport classes should be allowed to be registered, false otherwise.
* @param namedWriteableRegistry registry for named writeables for use during streaming
*/
public NetworkModule(NetworkService networkService, Settings settings, boolean transportClient, NamedWriteableRegistry namedWriteableRegistry) {
public NetworkModule(NetworkService networkService, Settings settings, boolean transportClient,
NamedWriteableRegistry namedWriteableRegistry) {
this.networkService = networkService;
this.settings = settings;
this.transportClient = transportClient;

View File

@ -33,7 +33,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -90,18 +89,12 @@ public class NetworkService extends AbstractComponent {
InetAddress[] resolveIfPossible(String value) throws IOException;
}
private final List<CustomNameResolver> customNameResolvers = new CopyOnWriteArrayList<>();
private final List<CustomNameResolver> customNameResolvers;
public NetworkService(Settings settings) {
public NetworkService(Settings settings, List<CustomNameResolver> customNameResolvers) {
super(settings);
IfConfig.logIfNecessary();
}
/**
* Add a custom name resolver.
*/
public void addCustomNameResolver(CustomNameResolver customNameResolver) {
customNameResolvers.add(customNameResolver);
this.customNameResolvers = customNameResolvers;
}
/**
@ -120,11 +113,13 @@ public class NetworkService extends AbstractComponent {
// if we have settings use them (we have a fallback to GLOBAL_NETWORK_HOST_SETTING inline
bindHosts = GLOBAL_NETWORK_BINDHOST_SETTING.get(settings).toArray(Strings.EMPTY_ARRAY);
} else {
// next check any registered custom resolvers
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
return addresses;
// next check any registered custom resolvers if any
if (customNameResolvers != null) {
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
return addresses;
}
}
}
// we know it's not here. get the defaults
@ -166,11 +161,13 @@ public class NetworkService extends AbstractComponent {
// if we have settings use them (we have a fallback to GLOBAL_NETWORK_HOST_SETTING inline
publishHosts = GLOBAL_NETWORK_PUBLISHHOST_SETTING.get(settings).toArray(Strings.EMPTY_ARRAY);
} else {
// next check any registered custom resolvers
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
return addresses[0];
// next check any registered custom resolvers if any
if (customNameResolvers != null) {
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveDefault();
if (addresses != null) {
return addresses[0];
}
}
}
// we know it's not here. get the defaults
@ -229,11 +226,13 @@ public class NetworkService extends AbstractComponent {
private InetAddress[] resolveInternal(String host) throws IOException {
if ((host.startsWith("#") && host.endsWith("#")) || (host.startsWith("_") && host.endsWith("_"))) {
host = host.substring(1, host.length() - 1);
// allow custom resolvers to have special names
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveIfPossible(host);
if (addresses != null) {
return addresses;
// next check any registered custom resolvers if any
if (customNameResolvers != null) {
for (CustomNameResolver customNameResolver : customNameResolvers) {
InetAddress addresses[] = customNameResolver.resolveIfPossible(host);
if (addresses != null) {
return addresses;
}
}
}
switch (host) {

View File

@ -92,6 +92,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer;
import org.elasticsearch.node.service.NodeService;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.AnalysisPlugin;
import org.elasticsearch.plugins.DiscoveryPlugin;
import org.elasticsearch.plugins.IngestPlugin;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.plugins.Plugin;
@ -294,7 +295,8 @@ public class Node implements Closeable {
// so we might be late here already
final SettingsModule settingsModule = new SettingsModule(this.settings, additionalSettings, additionalSettingsFilter);
resourcesToClose.add(resourceWatcherService);
final NetworkService networkService = new NetworkService(settings);
final NetworkService networkService = new NetworkService(settings,
getCustomNameResolvers(pluginsService.filterPlugins(DiscoveryPlugin.class)));
final ClusterService clusterService = new ClusterService(settings, settingsModule.getClusterSettings(), threadPool);
clusterService.add(scriptModule.getScriptService());
resourcesToClose.add(clusterService);
@ -721,4 +723,19 @@ public class Node implements Closeable {
BigArrays createBigArrays(Settings settings, CircuitBreakerService circuitBreakerService) {
return new BigArrays(settings, circuitBreakerService);
}
/**
* Get Custom Name Resolvers list based on a Discovery Plugins list
* @param discoveryPlugins Discovery plugins list
*/
private List<NetworkService.CustomNameResolver> getCustomNameResolvers(List<DiscoveryPlugin> discoveryPlugins) {
List<NetworkService.CustomNameResolver> customNameResolvers = new ArrayList<>();
for (DiscoveryPlugin discoveryPlugin : discoveryPlugins) {
NetworkService.CustomNameResolver customNameResolver = discoveryPlugin.getCustomNameResolver(settings);
if (customNameResolver != null) {
customNameResolvers.add(customNameResolver);
}
}
return customNameResolvers;
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.plugins;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
/**
* An additional extension point for {@link Plugin}s that extends Elasticsearch's discovery functionality. To add an additional
* {@link NetworkService.CustomNameResolver} just implement the interface and implement the {@link #getCustomNameResolver(Settings)} method:
*
* <pre>{@code
* public class MyDiscoveryPlugin extends Plugin implements DiscoveryPlugin {
* &#64;Override
* public NetworkService.CustomNameResolver getCustomNameResolver(Settings settings) {
* return new YourCustomNameResolverInstance(settings);
* }
* }
* }</pre>
*/
public interface DiscoveryPlugin {
/**
* Override to add additional {@link NetworkService.CustomNameResolver}s.
* This can be handy if you want to provide your own Network interface name like _mycard_
* and implement by yourself the logic to get an actual IP address/hostname based on this
* name.
*
* For example: you could call a third party service (an API) to resolve _mycard_.
* Then you could define in elasticsearch.yml settings like:
*
* <pre>{@code
* network.host: _mycard_
* }</pre>
*/
default NetworkService.CustomNameResolver getCustomNameResolver(Settings settings) {
return null;
}
}

View File

@ -45,12 +45,12 @@ import org.elasticsearch.test.rest.FakeRestRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import static java.util.Collections.emptyMap;
import static java.util.Collections.unmodifiableList;
import static org.elasticsearch.common.unit.TimeValue.timeValueMillis;

View File

@ -51,8 +51,11 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardNotFoundException;
import org.elasticsearch.plugins.DiscoveryPlugin;
import org.elasticsearch.test.ESAllocationTestCase;
import java.util.Collections;
import static java.util.Collections.singleton;
import static org.elasticsearch.cluster.routing.ShardRoutingState.INITIALIZING;
import static org.elasticsearch.cluster.routing.ShardRoutingState.RELOCATING;
@ -481,7 +484,7 @@ public class AllocationCommandsTests extends ESAllocationTestCase {
parser.nextToken();
parser.nextToken();
AllocationCommandRegistry registry = new NetworkModule(null, Settings.EMPTY, true, new NamedWriteableRegistry())
.getAllocationCommandRegistry();
.getAllocationCommandRegistry();
AllocationCommands sCommands = AllocationCommands.fromXContent(parser, ParseFieldMatcher.STRICT, registry);
assertThat(sCommands.commands().size(), equalTo(5));

View File

@ -44,6 +44,7 @@ import org.elasticsearch.transport.Transport;
import org.elasticsearch.transport.TransportService;
import java.io.IOException;
import java.util.Collections;
public class NetworkModuleTests extends ModuleTestCase {
@ -112,13 +113,14 @@ public class NetworkModuleTests extends ModuleTestCase {
.put(NetworkModule.HTTP_ENABLED.getKey(), false)
.put(NetworkModule.TRANSPORT_TYPE_KEY, "local")
.build();
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
NetworkModule module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, false,
new NamedWriteableRegistry());
module.registerTransportService("custom", FakeTransportService.class);
assertBinding(module, TransportService.class, FakeTransportService.class);
assertFalse(module.isTransportClient());
// check it works with transport only as well
module = new NetworkModule(new NetworkService(settings), settings, true, new NamedWriteableRegistry());
module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, true, new NamedWriteableRegistry());
module.registerTransportService("custom", FakeTransportService.class);
assertBinding(module, TransportService.class, FakeTransportService.class);
assertTrue(module.isTransportClient());
@ -128,13 +130,14 @@ public class NetworkModuleTests extends ModuleTestCase {
Settings settings = Settings.builder().put(NetworkModule.TRANSPORT_TYPE_KEY, "custom")
.put(NetworkModule.HTTP_ENABLED.getKey(), false)
.build();
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
NetworkModule module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, false,
new NamedWriteableRegistry());
module.registerTransport("custom", FakeTransport.class);
assertBinding(module, Transport.class, FakeTransport.class);
assertFalse(module.isTransportClient());
// check it works with transport only as well
module = new NetworkModule(new NetworkService(settings), settings, true, new NamedWriteableRegistry());
module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, true, new NamedWriteableRegistry());
module.registerTransport("custom", FakeTransport.class);
assertBinding(module, Transport.class, FakeTransport.class);
assertTrue(module.isTransportClient());
@ -144,13 +147,14 @@ public class NetworkModuleTests extends ModuleTestCase {
Settings settings = Settings.builder()
.put(NetworkModule.HTTP_TYPE_SETTING.getKey(), "custom")
.put(NetworkModule.TRANSPORT_TYPE_KEY, "local").build();
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
NetworkModule module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, false,
new NamedWriteableRegistry());
module.registerHttpTransport("custom", FakeHttpTransport.class);
assertBinding(module, HttpServerTransport.class, FakeHttpTransport.class);
assertFalse(module.isTransportClient());
// check registration not allowed for transport only
module = new NetworkModule(new NetworkService(settings), settings, true, new NamedWriteableRegistry());
module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, true, new NamedWriteableRegistry());
assertTrue(module.isTransportClient());
try {
module.registerHttpTransport("custom", FakeHttpTransport.class);
@ -163,7 +167,7 @@ public class NetworkModuleTests extends ModuleTestCase {
// not added if http is disabled
settings = Settings.builder().put(NetworkModule.HTTP_ENABLED.getKey(), false)
.put(NetworkModule.TRANSPORT_TYPE_KEY, "local").build();
module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, false, new NamedWriteableRegistry());
assertNotBound(module, HttpServerTransport.class);
assertFalse(module.isTransportClient());
}
@ -171,7 +175,7 @@ public class NetworkModuleTests extends ModuleTestCase {
public void testRegisterTaskStatus() {
NamedWriteableRegistry registry = new NamedWriteableRegistry();
Settings settings = Settings.EMPTY;
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, registry);
NetworkModule module = new NetworkModule(new NetworkService(settings, Collections.emptyList()), settings, false, registry);
assertFalse(module.isTransportClient());
// Builtin reader comes back

View File

@ -23,6 +23,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import java.net.InetAddress;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
@ -36,7 +37,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure exception if we bind to multicast ipv4 address
*/
public void testBindMulticastV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
try {
service.resolveBindHostAddresses(new String[] { "239.1.1.1" });
fail("should have hit exception");
@ -48,7 +49,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure exception if we bind to multicast ipv6 address
*/
public void testBindMulticastV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
try {
service.resolveBindHostAddresses(new String[] { "FF08::108" });
fail("should have hit exception");
@ -61,7 +62,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure exception if we publish to multicast ipv4 address
*/
public void testPublishMulticastV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
try {
service.resolvePublishHostAddresses(new String[] { "239.1.1.1" });
fail("should have hit exception");
@ -74,7 +75,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure exception if we publish to multicast ipv6 address
*/
public void testPublishMulticastV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
try {
service.resolvePublishHostAddresses(new String[] { "FF08::108" });
fail("should have hit exception");
@ -87,7 +88,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure specifying wildcard ipv4 address will bind to all interfaces
*/
public void testBindAnyLocalV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
assertEquals(InetAddress.getByName("0.0.0.0"), service.resolveBindHostAddresses(new String[] { "0.0.0.0" })[0]);
}
@ -95,7 +96,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure specifying wildcard ipv6 address will bind to all interfaces
*/
public void testBindAnyLocalV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
assertEquals(InetAddress.getByName("::"), service.resolveBindHostAddresses(new String[] { "::" })[0]);
}
@ -103,7 +104,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure specifying wildcard ipv4 address selects reasonable publish address
*/
public void testPublishAnyLocalV4() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
InetAddress address = service.resolvePublishHostAddresses(new String[] { "0.0.0.0" });
assertFalse(address.isAnyLocalAddress());
}
@ -112,7 +113,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure specifying wildcard ipv6 address selects reasonable publish address
*/
public void testPublishAnyLocalV6() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
InetAddress address = service.resolvePublishHostAddresses(new String[] { "::" });
assertFalse(address.isAnyLocalAddress());
}
@ -121,7 +122,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure we can bind to multiple addresses
*/
public void testBindMultipleAddresses() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
InetAddress[] addresses = service.resolveBindHostAddresses(new String[]{"127.0.0.1", "127.0.0.2"});
assertThat(addresses.length, is(2));
}
@ -130,7 +131,7 @@ public class NetworkServiceTests extends ESTestCase {
* ensure we can't bind to multiple addresses when using wildcard
*/
public void testBindMultipleAddressesWithWildcard() throws Exception {
NetworkService service = new NetworkService(Settings.EMPTY);
NetworkService service = new NetworkService(Settings.EMPTY, Collections.emptyList());
try {
service.resolveBindHostAddresses(new String[]{"0.0.0.0", "127.0.0.1"});
fail("should have hit exception");

View File

@ -45,6 +45,7 @@ import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.TransportSettings;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
@ -66,7 +67,7 @@ public class UnicastZenPingIT extends ESTestCase {
.put(TransportSettings.PORT.getKey(), startPort + "-" + endPort).build();
ThreadPool threadPool = new TestThreadPool(getClass().getName());
NetworkService networkService = new NetworkService(settings);
NetworkService networkService = new NetworkService(settings, Collections.emptyList());
ElectMasterService electMasterService = new ElectMasterService(settings);
NetworkHandle handleA = startServices(settings, threadPool, networkService, "UZP_A", Version.CURRENT);

View File

@ -36,6 +36,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -63,7 +64,7 @@ public class TransportServiceHandshakeTests extends ESTestCase {
BigArrays.NON_RECYCLING_INSTANCE,
new NoneCircuitBreakerService(),
new NamedWriteableRegistry(),
new NetworkService(settings));
new NetworkService(settings, Collections.emptyList()));
TransportService transportService = new MockTransportService(settings, transport, threadPool);
transportService.start();
transportService.acceptIncomingRequests();

View File

@ -50,6 +50,7 @@ import org.junit.Before;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.elasticsearch.http.HttpTransportSettings.SETTING_CORS_ALLOW_CREDENTIALS;
@ -70,7 +71,7 @@ public class Netty3HttpChannelTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -49,6 +49,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -72,7 +73,7 @@ public class Netty3HttpServerPipeliningTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -34,6 +34,7 @@ import org.junit.After;
import org.junit.Before;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@ -55,7 +56,7 @@ public class Netty3HttpServerTransportTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -38,6 +38,7 @@ import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
@ -61,7 +62,7 @@ public class Netty3SizeHeaderFrameDecoderTests extends ESTestCase {
@Before
public void startThreadPool() {
threadPool = new ThreadPool(settings);
NetworkService networkService = new NetworkService(settings);
NetworkService networkService = new NetworkService(settings, Collections.emptyList());
BigArrays bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
nettyTransport = new Netty3Transport(settings, threadPool, networkService, bigArrays, new NamedWriteableRegistry(),
new NoneCircuitBreakerService());

View File

@ -43,6 +43,7 @@ import org.elasticsearch.transport.TransportResponseOptions;
import org.elasticsearch.transport.TransportSettings;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
@ -62,14 +63,14 @@ public class Netty3ScheduledPingTests extends ESTestCase {
CircuitBreakerService circuitBreakerService = new NoneCircuitBreakerService();
NamedWriteableRegistry registryA = new NamedWriteableRegistry();
final Netty3Transport nettyA = new Netty3Transport(settings, threadPool, new NetworkService(settings),
final Netty3Transport nettyA = new Netty3Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, registryA, circuitBreakerService);
MockTransportService serviceA = new MockTransportService(settings, nettyA, threadPool);
serviceA.start();
serviceA.acceptIncomingRequests();
NamedWriteableRegistry registryB = new NamedWriteableRegistry();
final Netty3Transport nettyB = new Netty3Transport(settings, threadPool, new NetworkService(settings),
final Netty3Transport nettyB = new Netty3Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, registryB, circuitBreakerService);
MockTransportService serviceB = new MockTransportService(settings, nettyB, threadPool);

View File

@ -34,6 +34,8 @@ import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.TransportSettings;
import org.junit.Before;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
public class Netty3TransportMultiPortTests extends ESTestCase {
@ -135,8 +137,8 @@ public class Netty3TransportMultiPortTests extends ESTestCase {
private TcpTransport<?> startTransport(Settings settings, ThreadPool threadPool) {
BigArrays bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
TcpTransport<?> transport = new Netty3Transport(settings, threadPool, new NetworkService(settings), bigArrays,
new NamedWriteableRegistry(), new NoneCircuitBreakerService());
TcpTransport<?> transport = new Netty3Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
bigArrays, new NamedWriteableRegistry(), new NoneCircuitBreakerService());
transport.start();
assertThat(transport.lifecycleState(), is(Lifecycle.State.STARTED));

View File

@ -36,6 +36,7 @@ import org.elasticsearch.transport.TransportSettings;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
@ -47,8 +48,8 @@ public class SimpleNetty3TransportTests extends AbstractSimpleTransportTestCase
Settings settings,
ThreadPool threadPool, final Version version) {
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
Transport transport = new Netty3Transport(settings, threadPool, new NetworkService(settings), BigArrays.NON_RECYCLING_INSTANCE,
namedWriteableRegistry, new NoneCircuitBreakerService()) {
Transport transport = new Netty3Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, namedWriteableRegistry, new NoneCircuitBreakerService()) {
@Override
protected Version getCurrentVersion() {
return version;

View File

@ -58,6 +58,7 @@ import org.junit.Before;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.elasticsearch.http.HttpTransportSettings.SETTING_CORS_ALLOW_CREDENTIALS;
@ -77,7 +78,7 @@ public class Netty4HttpChannelTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -49,6 +49,7 @@ import org.junit.Before;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -67,7 +68,7 @@ public class Netty4HttpServerPipeliningTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -33,6 +33,7 @@ import org.junit.After;
import org.junit.Before;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@ -55,7 +56,7 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
@Before
public void setup() throws Exception {
networkService = new NetworkService(Settings.EMPTY);
networkService = new NetworkService(Settings.EMPTY, Collections.emptyList());
threadPool = new TestThreadPool("test");
bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
}

View File

@ -43,6 +43,7 @@ import org.elasticsearch.transport.TransportResponseOptions;
import org.elasticsearch.transport.TransportSettings;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
@ -62,14 +63,14 @@ public class Netty4ScheduledPingTests extends ESTestCase {
CircuitBreakerService circuitBreakerService = new NoneCircuitBreakerService();
NamedWriteableRegistry registryA = new NamedWriteableRegistry();
final Netty4Transport nettyA = new Netty4Transport(settings, threadPool, new NetworkService(settings),
final Netty4Transport nettyA = new Netty4Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, registryA, circuitBreakerService);
MockTransportService serviceA = new MockTransportService(settings, nettyA, threadPool);
serviceA.start();
serviceA.acceptIncomingRequests();
NamedWriteableRegistry registryB = new NamedWriteableRegistry();
final Netty4Transport nettyB = new Netty4Transport(settings, threadPool, new NetworkService(settings),
final Netty4Transport nettyB = new Netty4Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, registryB, circuitBreakerService);
MockTransportService serviceB = new MockTransportService(settings, nettyB, threadPool);

View File

@ -38,6 +38,7 @@ import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
@ -61,7 +62,7 @@ public class Netty4SizeHeaderFrameDecoderTests extends ESTestCase {
@Before
public void startThreadPool() {
threadPool = new ThreadPool(settings);
NetworkService networkService = new NetworkService(settings);
NetworkService networkService = new NetworkService(settings, Collections.emptyList());
BigArrays bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
nettyTransport = new Netty4Transport(settings, threadPool, networkService, bigArrays, new NamedWriteableRegistry(),
new NoneCircuitBreakerService());

View File

@ -34,6 +34,8 @@ import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.TransportSettings;
import org.junit.Before;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
public class NettyTransportMultiPortTests extends ESTestCase {
@ -135,8 +137,8 @@ public class NettyTransportMultiPortTests extends ESTestCase {
private TcpTransport<?> startTransport(Settings settings, ThreadPool threadPool) {
BigArrays bigArrays = new MockBigArrays(Settings.EMPTY, new NoneCircuitBreakerService());
TcpTransport<?> transport = new Netty4Transport(settings, threadPool, new NetworkService(settings), bigArrays,
new NamedWriteableRegistry(), new NoneCircuitBreakerService());
TcpTransport<?> transport = new Netty4Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
bigArrays, new NamedWriteableRegistry(), new NoneCircuitBreakerService());
transport.start();
assertThat(transport.lifecycleState(), is(Lifecycle.State.STARTED));

View File

@ -36,6 +36,7 @@ import org.elasticsearch.transport.TransportSettings;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
@ -47,8 +48,8 @@ public class SimpleNetty4TransportTests extends AbstractSimpleTransportTestCase
Settings settings,
ThreadPool threadPool, final Version version) {
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
Transport transport = new Netty4Transport(settings, threadPool, new NetworkService(settings), BigArrays.NON_RECYCLING_INSTANCE,
namedWriteableRegistry, new NoneCircuitBreakerService()) {
Transport transport = new Netty4Transport(settings, threadPool, new NetworkService(settings, Collections.emptyList()),
BigArrays.NON_RECYCLING_INSTANCE, namedWriteableRegistry, new NoneCircuitBreakerService()) {
@Override
protected Version getCurrentVersion() {
return version;

View File

@ -55,10 +55,8 @@ public class AwsEc2ServiceImpl extends AbstractLifecycleComponent implements Aws
private AmazonEC2Client client;
@Inject
public AwsEc2ServiceImpl(Settings settings, NetworkService networkService) {
public AwsEc2ServiceImpl(Settings settings) {
super(settings);
// add specific ec2 name resolver
networkService.addCustomNameResolver(new Ec2NameResolver(settings));
}
@Override

View File

@ -38,22 +38,26 @@ import org.elasticsearch.SpecialPermission;
import org.elasticsearch.cloud.aws.AwsEc2Service;
import org.elasticsearch.cloud.aws.AwsEc2ServiceImpl;
import org.elasticsearch.cloud.aws.Ec2Module;
import org.elasticsearch.cloud.aws.network.Ec2NameResolver;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.DiscoveryModule;
import org.elasticsearch.discovery.ec2.AwsEc2UnicastHostsProvider;
import org.elasticsearch.discovery.zen.ZenDiscovery;
import org.elasticsearch.node.Node;
import org.elasticsearch.plugins.DiscoveryPlugin;
import org.elasticsearch.plugins.Plugin;
/**
*
*/
public class Ec2DiscoveryPlugin extends Plugin {
public class Ec2DiscoveryPlugin extends Plugin implements DiscoveryPlugin {
private static ESLogger logger = Loggers.getLogger(Ec2DiscoveryPlugin.class);
@ -105,6 +109,12 @@ public class Ec2DiscoveryPlugin extends Plugin {
discoveryModule.addUnicastHostProvider(EC2, AwsEc2UnicastHostsProvider.class);
}
@Override
public NetworkService.CustomNameResolver getCustomNameResolver(Settings settings) {
logger.debug("Register _ec2_, _ec2:xxx_ network names");
return new Ec2NameResolver(settings);
}
@Override
public List<Setting<?>> getSettings() {
return Arrays.asList(

View File

@ -26,6 +26,7 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Collections;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;
@ -42,8 +43,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -60,8 +60,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:publicIp_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -78,8 +77,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:privateIp_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -96,8 +94,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:privateIpv4_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -114,8 +111,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:privateDns_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -132,8 +128,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:publicIpv4_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -150,8 +145,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_ec2:publicDns_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
// TODO we need to replace that with a mock. For now we check the URL we are supposed to reach.
try {
networkService.resolveBindHostAddresses(null);
@ -169,8 +163,7 @@ public class Ec2NetworkTests extends ESTestCase {
.put("network.host", "_local_")
.build();
NetworkService networkService = new NetworkService(nodeSettings);
networkService.addCustomNameResolver(new Ec2NameResolver(nodeSettings));
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new Ec2NameResolver(nodeSettings)));
InetAddress[] addresses = networkService.resolveBindHostAddresses(null);
assertThat(addresses, arrayContaining(networkService.resolveBindHostAddresses(new String[] { "_local_" })));
}

View File

@ -25,13 +25,12 @@ import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.unit.TimeValue;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
public interface GceComputeService extends LifecycleComponent {
public interface GceInstancesService extends LifecycleComponent {
/**
* GCE API Version: Elasticsearch/GceCloud/1.0
@ -76,19 +75,4 @@ public interface GceComputeService extends LifecycleComponent {
* @return a collection of running instances within the same GCE project
*/
Collection<Instance> instances();
/**
* <p>Gets metadata on the current running machine (call to
* http://metadata.google.internal/computeMetadata/v1/instance/xxx).</p>
* <p>For example, you can retrieve network information by replacing xxx with:</p>
* <ul>
* <li>`hostname` when we need to resolve the host name</li>
* <li>`network-interfaces/0/ip` when we need to resolve private IP</li>
* </ul>
* @see org.elasticsearch.cloud.gce.network.GceNameResolver for bindings
* @param metadataPath path to metadata information
* @return extracted information (for example a hostname or an IP address)
* @throws IOException in case metadata URL is not accessible
*/
String metadata(String metadataPath) throws IOException;
}

View File

@ -21,9 +21,6 @@ package org.elasticsearch.cloud.gce;
import com.google.api.client.googleapis.compute.ComputeCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
@ -33,10 +30,8 @@ import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.InstanceList;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.cloud.gce.network.GceNameResolver;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
@ -44,10 +39,8 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.gce.RetryHttpInitializerWrapper;
import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.GeneralSecurityException;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@ -56,27 +49,16 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Function;
public class GceComputeServiceImpl extends AbstractLifecycleComponent
implements GceComputeService {
public class GceInstancesServiceImpl extends AbstractLifecycleComponent implements GceInstancesService {
// all settings just used for testing - not registered by default
public static final Setting<Boolean> GCE_VALIDATE_CERTIFICATES =
Setting.boolSetting("cloud.gce.validate_certificates", true, Property.NodeScope);
public static final Setting<String> GCE_HOST =
new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), Property.NodeScope);
public static final Setting<String> GCE_ROOT_URL =
new Setting<>("cloud.gce.root_url", "https://www.googleapis.com", Function.identity(), Property.NodeScope);
private final String project;
private final List<String> zones;
// Forcing Google Token API URL as set in GCE SDK to
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
// See https://developers.google.com/compute/docs/metadata#metadataserver
private final String gceHost;
private final String metaDataUrl;
private final String tokenServerEncodedUrl;
private String gceRootUrl;
@Override
public Collection<Instance> instances() {
@ -117,47 +99,6 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent
return instances;
}
@Override
public String metadata(String metadataPath) throws IOException {
String urlMetadataNetwork = this.metaDataUrl + "/" + metadataPath;
logger.debug("get metadata from [{}]", urlMetadataNetwork);
final URL url = new URL(urlMetadataNetwork);
HttpHeaders headers;
try {
// hack around code messiness in GCE code
// TODO: get this fixed
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
headers = AccessController.doPrivileged(new PrivilegedExceptionAction<HttpHeaders>() {
@Override
public HttpHeaders run() throws IOException {
return new HttpHeaders();
}
});
GenericUrl genericUrl = AccessController.doPrivileged(new PrivilegedAction<GenericUrl>() {
@Override
public GenericUrl run() {
return new GenericUrl(url);
}
});
// This is needed to query meta data: https://cloud.google.com/compute/docs/metadata
headers.put("Metadata-Flavor", "Google");
HttpResponse response;
response = getGceHttpTransport().createRequestFactory()
.buildGetRequest(genericUrl)
.setHeaders(headers)
.execute();
String metadata = response.parseAsString();
logger.debug("metadata found [{}]", metadata);
return metadata;
} catch (Exception e) {
throw new IOException("failed to fetch metadata from [" + urlMetadataNetwork + "]", e);
}
}
private Compute client;
private TimeValue refreshInterval = null;
private long lastRefresh;
@ -169,17 +110,13 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent
private JsonFactory gceJsonFactory;
private final boolean validateCerts;
@Inject
public GceComputeServiceImpl(Settings settings, NetworkService networkService) {
public GceInstancesServiceImpl(Settings settings) {
super(settings);
this.project = PROJECT_SETTING.get(settings);
this.zones = ZONE_SETTING.get(settings);
this.gceHost = GCE_HOST.get(settings);
this.metaDataUrl = gceHost + "/computeMetadata/v1/instance";
this.gceRootUrl = GCE_ROOT_URL.get(settings);
tokenServerEncodedUrl = metaDataUrl + "/service-accounts/default/token";
this.validateCerts = GCE_VALIDATE_CERTIFICATES.get(settings);
networkService.addCustomNameResolver(new GceNameResolver(settings, this));
}
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
@ -208,8 +145,13 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent
gceJsonFactory = new JacksonFactory();
logger.info("starting GCE discovery service");
// Forcing Google Token API URL as set in GCE SDK to
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
// See https://developers.google.com/compute/docs/metadata#metadataserver
String tokenServerEncodedUrl = GceMetadataService.GCE_HOST.get(settings) +
"/computeMetadata/v1/instance/service-accounts/default/token";
ComputeCredential credential = new ComputeCredential.Builder(getGceHttpTransport(), gceJsonFactory)
.setTokenServerEncodedUrl(this.tokenServerEncodedUrl)
.setTokenServerEncodedUrl(tokenServerEncodedUrl)
.build();
// hack around code messiness in GCE code
@ -233,7 +175,7 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent
Compute.Builder builder = new Compute.Builder(getGceHttpTransport(), gceJsonFactory, null).setApplicationName(VERSION)
.setRootUrl(gceRootUrl);
.setRootUrl(GCE_ROOT_URL.get(settings));
if (RETRY_SETTING.exists(settings)) {
TimeValue maxWait = MAX_WAIT_SETTING.get(settings);

View File

@ -0,0 +1,131 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.cloud.gce;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.cloud.gce.network.GceNameResolver;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.AccessController;
import java.security.GeneralSecurityException;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.function.Function;
public class GceMetadataService extends AbstractLifecycleComponent {
// Forcing Google Token API URL as set in GCE SDK to
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
// See https://developers.google.com/compute/docs/metadata#metadataserver
// all settings just used for testing - not registered by default
public static final Setting<String> GCE_HOST =
new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), Setting.Property.NodeScope);
/** Global instance of the HTTP transport. */
private HttpTransport gceHttpTransport;
@Inject
public GceMetadataService(Settings settings) {
super(settings);
}
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
if (gceHttpTransport == null) {
gceHttpTransport = GoogleNetHttpTransport.newTrustedTransport();
}
return gceHttpTransport;
}
public String metadata(String metadataPath) throws IOException, URISyntaxException {
// Forcing Google Token API URL as set in GCE SDK to
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
// See https://developers.google.com/compute/docs/metadata#metadataserver
final URI urlMetadataNetwork = new URI(GCE_HOST.get(settings)).resolve("/computeMetadata/v1/instance/").resolve(metadataPath);
logger.debug("get metadata from [{}]", urlMetadataNetwork);
HttpHeaders headers;
try {
// hack around code messiness in GCE code
// TODO: get this fixed
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
headers = AccessController.doPrivileged(new PrivilegedExceptionAction<HttpHeaders>() {
@Override
public HttpHeaders run() throws IOException {
return new HttpHeaders();
}
});
GenericUrl genericUrl = AccessController.doPrivileged(new PrivilegedAction<GenericUrl>() {
@Override
public GenericUrl run() {
return new GenericUrl(urlMetadataNetwork);
}
});
// This is needed to query meta data: https://cloud.google.com/compute/docs/metadata
headers.put("Metadata-Flavor", "Google");
HttpResponse response;
response = getGceHttpTransport().createRequestFactory()
.buildGetRequest(genericUrl)
.setHeaders(headers)
.execute();
String metadata = response.parseAsString();
logger.debug("metadata found [{}]", metadata);
return metadata;
} catch (Exception e) {
throw new IOException("failed to fetch metadata from [" + urlMetadataNetwork + "]", e);
}
}
@Override
protected void doStart() {
}
@Override
protected void doStop() {
if (gceHttpTransport != null) {
try {
gceHttpTransport.shutdown();
} catch (IOException e) {
logger.warn("unable to shutdown GCE Http Transport", e);
}
gceHttpTransport = null;
}
}
@Override
protected void doClose() {
}
}

View File

@ -20,17 +20,28 @@
package org.elasticsearch.cloud.gce;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
public class GceModule extends AbstractModule {
// pkg private so tests can override with mock
static Class<? extends GceComputeService> computeServiceImpl = GceComputeServiceImpl.class;
static Class<? extends GceInstancesService> computeServiceImpl = GceInstancesServiceImpl.class;
public static Class<? extends GceComputeService> getComputeServiceImpl() {
protected final Settings settings;
protected final ESLogger logger = Loggers.getLogger(GceModule.class);
public GceModule(Settings settings) {
this.settings = settings;
}
public static Class<? extends GceInstancesService> getComputeServiceImpl() {
return computeServiceImpl;
}
@Override
protected void configure() {
bind(GceComputeService.class).to(computeServiceImpl).asEagerSingleton();
logger.debug("configure GceModule (bind compute service)");
bind(GceInstancesService.class).to(computeServiceImpl).asEagerSingleton();
}
}

View File

@ -19,7 +19,7 @@
package org.elasticsearch.cloud.gce.network;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.cloud.gce.GceMetadataService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.network.NetworkService.CustomNameResolver;
@ -27,6 +27,7 @@ import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URISyntaxException;
/**
* <p>Resolves certain GCE related 'meta' hostnames into an actual hostname
@ -40,7 +41,7 @@ import java.net.InetAddress;
*/
public class GceNameResolver extends AbstractComponent implements CustomNameResolver {
private final GceComputeService gceComputeService;
private final GceMetadataService gceMetadataService;
/**
* enum that can be added to over time with more meta-data types
@ -72,9 +73,9 @@ public class GceNameResolver extends AbstractComponent implements CustomNameReso
/**
* Construct a {@link CustomNameResolver}.
*/
public GceNameResolver(Settings settings, GceComputeService gceComputeService) {
public GceNameResolver(Settings settings, GceMetadataService gceMetadataService) {
super(settings);
this.gceComputeService = gceComputeService;
this.gceMetadataService = gceMetadataService;
}
/**
@ -93,7 +94,7 @@ public class GceNameResolver extends AbstractComponent implements CustomNameReso
// We extract the network interface from gce:privateIp:XX
String network = "0";
String[] privateIpConfig = value.split(":");
if (privateIpConfig != null && privateIpConfig.length == 3) {
if (privateIpConfig.length == 3) {
network = privateIpConfig[2];
}
@ -105,13 +106,13 @@ public class GceNameResolver extends AbstractComponent implements CustomNameReso
}
try {
String metadataResult = gceComputeService.metadata(gceMetadataPath);
String metadataResult = gceMetadataService.metadata(gceMetadataPath);
if (metadataResult == null || metadataResult.length() == 0) {
throw new IOException("no gce metadata returned from [" + gceMetadataPath + "] for [" + value + "]");
}
// only one address: because we explicitly ask for only one via the GceHostnameType
return new InetAddress[] { InetAddress.getByName(metadataResult) };
} catch (IOException e) {
} catch (IOException | URISyntaxException e) {
throw new IOException("IOException caught when fetching InetAddress from [" + gceMetadataPath + "]", e);
}
}

View File

@ -23,7 +23,7 @@ import com.google.api.services.compute.model.AccessConfig;
import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.NetworkInterface;
import org.elasticsearch.Version;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.cloud.gce.GceInstancesService;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent;
@ -64,7 +64,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
private static final String TERMINATED = "TERMINATED";
}
private final GceComputeService gceComputeService;
private final GceInstancesService gceInstancesService;
private TransportService transportService;
private NetworkService networkService;
@ -77,17 +77,17 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
private List<DiscoveryNode> cachedDiscoNodes;
@Inject
public GceUnicastHostsProvider(Settings settings, GceComputeService gceComputeService,
public GceUnicastHostsProvider(Settings settings, GceInstancesService gceInstancesService,
TransportService transportService,
NetworkService networkService) {
super(settings);
this.gceComputeService = gceComputeService;
this.gceInstancesService = gceInstancesService;
this.transportService = transportService;
this.networkService = networkService;
this.refreshInterval = GceComputeService.REFRESH_SETTING.get(settings);
this.project = GceComputeService.PROJECT_SETTING.get(settings);
this.zones = GceComputeService.ZONE_SETTING.get(settings);
this.refreshInterval = GceInstancesService.REFRESH_SETTING.get(settings);
this.project = GceInstancesService.PROJECT_SETTING.get(settings);
this.zones = GceInstancesService.ZONE_SETTING.get(settings);
this.tags = TAGS_SETTING.get(settings);
if (logger.isDebugEnabled()) {
@ -104,8 +104,8 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
// We check that needed properties have been set
if (this.project == null || this.project.isEmpty() || this.zones == null || this.zones.isEmpty()) {
throw new IllegalArgumentException("one or more gce discovery settings are missing. " +
"Check elasticsearch.yml file. Should have [" + GceComputeService.PROJECT_SETTING.getKey() +
"] and [" + GceComputeService.ZONE_SETTING.getKey() + "].");
"Check elasticsearch.yml file. Should have [" + GceInstancesService.PROJECT_SETTING.getKey() +
"] and [" + GceInstancesService.ZONE_SETTING.getKey() + "].");
}
if (refreshInterval.millis() != 0) {
@ -131,7 +131,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
}
try {
Collection<Instance> instances = gceComputeService.instances();
Collection<Instance> instances = gceInstancesService.instances();
if (instances == null) {
logger.trace("no instance found for project [{}], zones [{}].", this.project, this.zones);

View File

@ -22,30 +22,36 @@ package org.elasticsearch.plugin.discovery.gce;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.util.ClassInfo;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.cloud.gce.GceInstancesService;
import org.elasticsearch.cloud.gce.GceMetadataService;
import org.elasticsearch.cloud.gce.GceModule;
import org.elasticsearch.cloud.gce.network.GceNameResolver;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsModule;
import org.elasticsearch.discovery.DiscoveryModule;
import org.elasticsearch.discovery.gce.GceUnicastHostsProvider;
import org.elasticsearch.discovery.zen.ZenDiscovery;
import org.elasticsearch.plugins.DiscoveryPlugin;
import org.elasticsearch.plugins.Plugin;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class GceDiscoveryPlugin extends Plugin {
public class GceDiscoveryPlugin extends Plugin implements DiscoveryPlugin {
public static final String GCE = "gce";
private final Settings settings;
protected final ESLogger logger = Loggers.getLogger(GceDiscoveryPlugin.class);
static {
/*
@ -69,32 +75,46 @@ public class GceDiscoveryPlugin extends Plugin {
});
}
public GceDiscoveryPlugin(Settings settings) {
this.settings = settings;
logger.trace("starting gce discovery plugin...");
}
@Override
public Collection<Module> createGuiceModules() {
return Collections.singletonList(new GceModule());
return Collections.singletonList(new GceModule(settings));
}
@Override
@SuppressWarnings("rawtypes") // Supertype uses raw type
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
return Collections.singletonList(GceModule.getComputeServiceImpl());
logger.debug("Register gce compute service");
Collection<Class<? extends LifecycleComponent>> services = new ArrayList<>();
services.add(GceModule.getComputeServiceImpl());
return services;
}
public void onModule(DiscoveryModule discoveryModule) {
logger.debug("Register gce discovery type and gce unicast provider");
discoveryModule.addDiscoveryType(GCE, ZenDiscovery.class);
// If discovery.type: gce, we add Gce as a unicast provider
discoveryModule.addUnicastHostProvider(GCE, GceUnicastHostsProvider.class);
discoveryModule.addUnicastHostProvider(GCE, GceUnicastHostsProvider.class);
}
@Override
public NetworkService.CustomNameResolver getCustomNameResolver(Settings settings) {
logger.debug("Register _gce_, _gce:xxx network names");
return new GceNameResolver(settings, new GceMetadataService(settings));
}
@Override
public List<Setting<?>> getSettings() {
return Arrays.asList(
// Register GCE settings
GceComputeService.PROJECT_SETTING,
GceComputeService.ZONE_SETTING,
GceUnicastHostsProvider.TAGS_SETTING,
GceComputeService.REFRESH_SETTING,
GceComputeService.RETRY_SETTING,
GceComputeService.MAX_WAIT_SETTING);
// Register GCE settings
GceInstancesService.PROJECT_SETTING,
GceInstancesService.ZONE_SETTING,
GceUnicastHostsProvider.TAGS_SETTING,
GceInstancesService.REFRESH_SETTING,
GceInstancesService.RETRY_SETTING,
GceInstancesService.MAX_WAIT_SETTING);
}
}

View File

@ -23,14 +23,14 @@ import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
import org.elasticsearch.cloud.gce.GceComputeServiceImpl;
import org.elasticsearch.cloud.gce.GceInstancesServiceImpl;
import org.elasticsearch.cloud.gce.GceMetadataService;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsModule;
import org.elasticsearch.plugin.discovery.gce.GceDiscoveryPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase;
@ -67,8 +67,8 @@ public class GceDiscoverTests extends ESIntegTestCase {
public static class TestPlugin extends Plugin {
@Override
public List<Setting<?>> getSettings() {
return Arrays.asList(GceComputeServiceImpl.GCE_HOST, GceComputeServiceImpl.GCE_ROOT_URL,
GceComputeServiceImpl.GCE_VALIDATE_CERTIFICATES);
return Arrays.asList(GceMetadataService.GCE_HOST, GceInstancesServiceImpl.GCE_ROOT_URL,
GceInstancesServiceImpl.GCE_VALIDATE_CERTIFICATES);
}
}
@ -113,7 +113,7 @@ public class GceDiscoverTests extends ESIntegTestCase {
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress().getHostAddress(), 0), 0);
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
httpServer.createContext("/computeMetadata/v1/instance/service-accounts/default/token", (s) -> {
String response = GceComputeServiceMock.readGoogleInternalJsonResponse(
String response = GceMockUtils.readGoogleInternalJsonResponse(
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token");
byte[] responseAsBytes = response.getBytes(StandardCharsets.UTF_8);
s.sendResponseHeaders(200, responseAsBytes.length);

View File

@ -20,8 +20,7 @@
package org.elasticsearch.discovery.gce;
import org.elasticsearch.Version;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cloud.gce.GceInstancesServiceImpl;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
@ -34,6 +33,7 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@ -67,8 +67,7 @@ public class GceDiscoveryTests extends ESTestCase {
protected static ThreadPool threadPool;
protected MockTransportService transportService;
protected NetworkService networkService;
protected GceComputeService mock;
protected GceInstancesServiceMock mock;
protected String projectName;
@BeforeClass
@ -98,11 +97,6 @@ public class GceDiscoveryTests extends ESTestCase {
transportService = MockTransportService.local(Settings.EMPTY, Version.CURRENT, threadPool);
}
@Before
public void createNetworkService() {
networkService = new NetworkService(Settings.EMPTY);
}
@After
public void stopGceComputeService() {
if (mock != null) {
@ -110,9 +104,9 @@ public class GceDiscoveryTests extends ESTestCase {
}
}
protected List<DiscoveryNode> buildDynamicNodes(GceComputeService gceComputeService, Settings nodeSettings) {
GceUnicastHostsProvider provider = new GceUnicastHostsProvider(nodeSettings, gceComputeService, transportService,
new NetworkService(Settings.EMPTY));
protected List<DiscoveryNode> buildDynamicNodes(GceInstancesServiceImpl gceInstancesService, Settings nodeSettings) {
GceUnicastHostsProvider provider = new GceUnicastHostsProvider(nodeSettings, gceInstancesService,
transportService, new NetworkService(Settings.EMPTY, Collections.emptyList()));
List<DiscoveryNode> discoveryNodes = provider.buildDynamicNodes();
logger.info("--> nodes found: {}", discoveryNodes);
@ -121,21 +115,21 @@ public class GceDiscoveryTests extends ESTestCase {
public void testNodesWithDifferentTagsAndNoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
public void testNodesWithDifferentTagsAndOneTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(1));
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
@ -143,11 +137,11 @@ public class GceDiscoveryTests extends ESTestCase {
public void testNodesWithDifferentTagsAndTwoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(1));
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
@ -155,52 +149,52 @@ public class GceDiscoveryTests extends ESTestCase {
public void testNodesWithSameTagsAndNoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
public void testNodesWithSameTagsAndOneTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
public void testNodesWithSameTagsAndTwoTagsSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b")
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
public void testMultipleZonesAndTwoNodesInSameZone() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.putArray(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
public void testMultipleZonesAndTwoNodesInDifferentZones() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.putArray(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@ -210,17 +204,17 @@ public class GceDiscoveryTests extends ESTestCase {
*/
public void testZeroNode43() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.putArray(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(0));
}
public void testIllegalSettingsMissingAllRequired() {
Settings nodeSettings = Settings.EMPTY;
mock = new GceComputeServiceMock(Settings.EMPTY, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
try {
buildDynamicNodes(mock, nodeSettings);
fail("We expect an IllegalArgumentException for incomplete settings");
@ -231,9 +225,9 @@ public class GceDiscoveryTests extends ESTestCase {
public void testIllegalSettingsMissingProject() {
Settings nodeSettings = Settings.builder()
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
.putArray(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
try {
buildDynamicNodes(mock, nodeSettings);
fail("We expect an IllegalArgumentException for incomplete settings");
@ -244,9 +238,9 @@ public class GceDiscoveryTests extends ESTestCase {
public void testIllegalSettingsMissingZone() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
try {
buildDynamicNodes(mock, nodeSettings);
fail("We expect an IllegalArgumentException for incomplete settings");
@ -262,10 +256,10 @@ public class GceDiscoveryTests extends ESTestCase {
*/
public void testNoRegionReturnsEmptyList() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
.putArray(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b", "us-central1-a")
.put(GceInstancesServiceImpl.PROJECT_SETTING.getKey(), projectName)
.putArray(GceInstancesServiceImpl.ZONE_SETTING.getKey(), "europe-west1-b", "us-central1-a")
.build();
mock = new GceComputeServiceMock(nodeSettings, networkService);
mock = new GceInstancesServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(1));
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.discovery.gce;
import com.google.api.client.http.HttpTransport;
import org.elasticsearch.cloud.gce.GceInstancesServiceImpl;
import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import java.security.GeneralSecurityException;
/**
*
*/
public class GceInstancesServiceMock extends GceInstancesServiceImpl {
protected HttpTransport mockHttpTransport;
public GceInstancesServiceMock(Settings settings) {
super(settings);
this.mockHttpTransport = GceMockUtils.configureMock();
}
@Override
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
return this.mockHttpTransport;
}
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.discovery.gce;
import com.google.api.client.http.HttpTransport;
import org.elasticsearch.cloud.gce.GceMetadataService;
import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import java.security.GeneralSecurityException;
/**
* Mock for GCE Metadata Service
*/
public class GceMetadataServiceMock extends GceMetadataService {
protected HttpTransport mockHttpTransport;
public GceMetadataServiceMock(Settings settings) {
super(settings);
this.mockHttpTransport = GceMockUtils.configureMock();
}
@Override
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
return this.mockHttpTransport;
}
}

View File

@ -26,38 +26,22 @@ import com.google.api.client.json.Json;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import org.elasticsearch.cloud.gce.GceComputeServiceImpl;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.util.Callback;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.GeneralSecurityException;
/**
*
*/
public class GceComputeServiceMock extends GceComputeServiceImpl {
protected HttpTransport mockHttpTransport;
public GceComputeServiceMock(Settings settings, NetworkService networkService) {
super(settings, networkService);
this.mockHttpTransport = configureMock();
}
@Override
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
return this.mockHttpTransport;
}
public class GceMockUtils {
protected static final ESLogger logger = Loggers.getLogger(GceMockUtils.class);
public static final String GCE_METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/instance";
protected HttpTransport configureMock() {
protected static HttpTransport configureMock() {
return new MockHttpTransport() {
@Override
public LowLevelHttpRequest buildRequest(String method, final String url) throws IOException {
@ -94,7 +78,7 @@ public class GceComputeServiceMock extends GceComputeServiceImpl {
// We extract from the url the mock file path we want to use
String mockFileName = Strings.replace(url, urlRoot, "");
URL resource = GceComputeServiceMock.class.getResource(mockFileName);
URL resource = GceMockUtils.class.getResource(mockFileName);
if (resource == null) {
throw new IOException("can't read [" + url + "] in src/test/resources/org/elasticsearch/discovery/gce");
}

View File

@ -26,6 +26,8 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;
@ -79,7 +81,8 @@ public class GceNetworkTests extends ESTestCase {
* network.host: _local_
*/
public void networkHostCoreLocal() throws IOException {
resolveGce("_local_", new NetworkService(Settings.EMPTY).resolveBindHostAddresses(new String[] { NetworkService.DEFAULT_NETWORK_HOST }));
resolveGce("_local_", new NetworkService(Settings.EMPTY, Collections.emptyList())
.resolveBindHostAddresses(new String[] { NetworkService.DEFAULT_NETWORK_HOST }));
}
/**
@ -103,9 +106,8 @@ public class GceNetworkTests extends ESTestCase {
.put("network.host", gceNetworkSetting)
.build();
NetworkService networkService = new NetworkService(nodeSettings);
GceComputeServiceMock mock = new GceComputeServiceMock(nodeSettings, networkService);
networkService.addCustomNameResolver(new GceNameResolver(nodeSettings, mock));
GceMetadataServiceMock mock = new GceMetadataServiceMock(nodeSettings);
NetworkService networkService = new NetworkService(nodeSettings, Collections.singletonList(new GceNameResolver(nodeSettings, mock)));
try {
InetAddress[] addresses = networkService.resolveBindHostAddresses(null);
if (expected == null) {

View File

@ -26,12 +26,14 @@ import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.test.transport.MockTransportService;
import java.util.Collections;
public class MockTcpTransportTests extends AbstractSimpleTransportTestCase {
@Override
protected MockTransportService build(Settings settings, Version version) {
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
Transport transport = new MockTcpTransport(settings, threadPool, BigArrays.NON_RECYCLING_INSTANCE,
new NoneCircuitBreakerService(), namedWriteableRegistry, new NetworkService(settings), version);
new NoneCircuitBreakerService(), namedWriteableRegistry, new NetworkService(settings, Collections.emptyList()), version);
MockTransportService mockTransportService = new MockTransportService(Settings.EMPTY, transport, threadPool);
mockTransportService.start();
return mockTransportService;