mirror of https://github.com/apache/cassandra
Add AzureSnitch
As we were implementing the snitch itself, we noticed that the constructors for cloud-based snitches are unnecessarilly complicated and we took the opportunity to make them simpler. patch by Stefan Miklosovic; reviewed by German Eichberger and Jacek Lewandowski for CASSANDRA-18646
This commit is contained in:
parent
6643ea7551
commit
c273017b25
|
|
@ -1,4 +1,5 @@
|
||||||
5.0
|
5.0
|
||||||
|
* Add AzureSnitch (CASSANDRA-18646)
|
||||||
* Implementation of the Unified Compaction Strategy as described in CEP-26 (CASSANDRA-18397)
|
* Implementation of the Unified Compaction Strategy as described in CEP-26 (CASSANDRA-18397)
|
||||||
* Upgrade commons cli to 1.5.0 (CASSANDRA-18659)
|
* Upgrade commons cli to 1.5.0 (CASSANDRA-18659)
|
||||||
* Disable the deprecated keyspace/table thresholds and convert them to guardrails (CASSANDRA-18617)
|
* Disable the deprecated keyspace/table thresholds and convert them to guardrails (CASSANDRA-18617)
|
||||||
|
|
|
||||||
1
NEWS.txt
1
NEWS.txt
|
|
@ -172,6 +172,7 @@ New features
|
||||||
- `cassandra-stress` has a new option called '-jmx' which enables a user to pass username and password to JMX (CASSANDRA-18544)
|
- `cassandra-stress` has a new option called '-jmx' which enables a user to pass username and password to JMX (CASSANDRA-18544)
|
||||||
- It is possible to read all credentials for `cassandra-stress` from a file via option `-credentials-file` (CASSANDRA-18544)
|
- It is possible to read all credentials for `cassandra-stress` from a file via option `-credentials-file` (CASSANDRA-18544)
|
||||||
- nodetool info displays bootstrap state a node is in as well as if it was decommissioned or if it failed to decommission (CASSANDRA-18555)
|
- nodetool info displays bootstrap state a node is in as well as if it was decommissioned or if it failed to decommission (CASSANDRA-18555)
|
||||||
|
- Added snitch for Microsoft Azure of name AzureSnitch (CASSANDRA-18646)
|
||||||
|
|
||||||
Upgrading
|
Upgrading
|
||||||
---------
|
---------
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ rack=rack1
|
||||||
# it is refreshed. Defaults to 21600. Can not be smaller than 30 and bigger than 21600. Has to be an integer.
|
# it is refreshed. Defaults to 21600. Can not be smaller than 30 and bigger than 21600. Has to be an integer.
|
||||||
# ec2_metadata_token_ttl_seconds=21600
|
# ec2_metadata_token_ttl_seconds=21600
|
||||||
|
|
||||||
|
# AzureSnitch
|
||||||
|
# Options are:
|
||||||
|
# Version of API to talk to. When not set, defaults to '2021-12-13'.
|
||||||
|
# azure_api_version=2021-12-13
|
||||||
|
|
||||||
# For all cloud-based snitches, there are following options available:
|
# For all cloud-based snitches, there are following options available:
|
||||||
#
|
#
|
||||||
# Property to change metadata service url for a cloud-based snitch. The endpoint of a particular
|
# Property to change metadata service url for a cloud-based snitch. The endpoint of a particular
|
||||||
|
|
|
||||||
|
|
@ -1316,6 +1316,11 @@ slow_query_log_timeout: 500ms
|
||||||
# Snitch for getting dc and rack of a node from metadata service of Alibaba cloud.
|
# Snitch for getting dc and rack of a node from metadata service of Alibaba cloud.
|
||||||
# This snitch that assumes an ECS region is a DC and an ECS availability_zone is a rack.
|
# This snitch that assumes an ECS region is a DC and an ECS availability_zone is a rack.
|
||||||
#
|
#
|
||||||
|
# AzureSnitch:
|
||||||
|
# Gets datacenter from 'location' and rack from 'zone' fields of 'compute' object
|
||||||
|
# from instance metadata service. If the availability zone is not enabled, it will use the fault
|
||||||
|
# domain and get its respective value.
|
||||||
|
#
|
||||||
# CloudstackSnitch:
|
# CloudstackSnitch:
|
||||||
# A snitch that assumes a Cloudstack Zone follows the typical convention
|
# A snitch that assumes a Cloudstack Zone follows the typical convention
|
||||||
# country-location-az and uses a country/location tuple as a datacenter
|
# country-location-az and uses a country/location tuple as a datacenter
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,11 @@ abstract class AbstractCloudMetadataServiceConnector
|
||||||
protected final String metadataServiceUrl;
|
protected final String metadataServiceUrl;
|
||||||
protected final int requestTimeoutMs;
|
protected final int requestTimeoutMs;
|
||||||
|
|
||||||
public AbstractCloudMetadataServiceConnector(SnitchProperties properties)
|
private final SnitchProperties properties;
|
||||||
|
|
||||||
|
public AbstractCloudMetadataServiceConnector(SnitchProperties snitchProperties)
|
||||||
{
|
{
|
||||||
|
this.properties = snitchProperties;
|
||||||
String parsedMetadataServiceUrl = properties.get(METADATA_URL_PROPERTY, null);
|
String parsedMetadataServiceUrl = properties.get(METADATA_URL_PROPERTY, null);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -65,7 +68,6 @@ abstract class AbstractCloudMetadataServiceConnector
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String metadataRequestTimeout = properties.get(METADATA_REQUEST_TIMEOUT_PROPERTY, DEFAULT_METADATA_REQUEST_TIMEOUT);
|
String metadataRequestTimeout = properties.get(METADATA_REQUEST_TIMEOUT_PROPERTY, DEFAULT_METADATA_REQUEST_TIMEOUT);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -80,6 +82,11 @@ abstract class AbstractCloudMetadataServiceConnector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SnitchProperties getProperties()
|
||||||
|
{
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
public final String apiCall(String query) throws IOException
|
public final String apiCall(String query) throws IOException
|
||||||
{
|
{
|
||||||
return apiCall(metadataServiceUrl, query, "GET", ImmutableMap.of(), 200);
|
return apiCall(metadataServiceUrl, query, "GET", ImmutableMap.of(), 200);
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,20 @@ abstract class AbstractCloudMetadataServiceSnitch extends AbstractNetworkTopolog
|
||||||
static final String DEFAULT_RACK = "UNKNOWN-RACK";
|
static final String DEFAULT_RACK = "UNKNOWN-RACK";
|
||||||
|
|
||||||
protected final AbstractCloudMetadataServiceConnector connector;
|
protected final AbstractCloudMetadataServiceConnector connector;
|
||||||
protected final SnitchProperties snitchProperties;
|
|
||||||
|
|
||||||
private final String localRack;
|
private final String localRack;
|
||||||
private final String localDc;
|
private final String localDc;
|
||||||
|
|
||||||
private Map<InetAddressAndPort, Map<String, String>> savedEndpoints;
|
private Map<InetAddressAndPort, Map<String, String>> savedEndpoints;
|
||||||
|
|
||||||
public AbstractCloudMetadataServiceSnitch(AbstractCloudMetadataServiceConnector connector,
|
public AbstractCloudMetadataServiceSnitch(AbstractCloudMetadataServiceConnector connector, Pair<String, String> dcAndRack)
|
||||||
SnitchProperties snitchProperties,
|
|
||||||
Pair<String, String> dcAndRack)
|
|
||||||
{
|
{
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
this.snitchProperties = snitchProperties;
|
|
||||||
this.localDc = dcAndRack.left;
|
this.localDc = dcAndRack.left;
|
||||||
this.localRack = dcAndRack.right;
|
this.localRack = dcAndRack.right;
|
||||||
|
|
||||||
logger.info(format("%s using datacenter: %s, rack: %s, connector: %s, properties: %s",
|
logger.info(format("%s using datacenter: %s, rack: %s, connector: %s, properties: %s",
|
||||||
getClass().getName(), getLocalDatacenter(), getLocalRack(), connector, snitchProperties));
|
getClass().getName(), getLocalDatacenter(), getLocalRack(), connector, connector.getProperties()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ package org.apache.cassandra.locator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
|
|
||||||
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
|
|
@ -44,14 +42,13 @@ public class AlibabaCloudSnitch extends AbstractCloudMetadataServiceSnitch
|
||||||
|
|
||||||
public AlibabaCloudSnitch(SnitchProperties properties) throws IOException
|
public AlibabaCloudSnitch(SnitchProperties properties) throws IOException
|
||||||
{
|
{
|
||||||
this(properties, new DefaultCloudMetadataServiceConnector(properties.putIfAbsent(METADATA_URL_PROPERTY,
|
this(new DefaultCloudMetadataServiceConnector(properties.putIfAbsent(METADATA_URL_PROPERTY,
|
||||||
DEFAULT_METADATA_SERVICE_URL)));
|
DEFAULT_METADATA_SERVICE_URL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlibabaCloudSnitch(SnitchProperties properties, AbstractCloudMetadataServiceConnector connector) throws IOException
|
public AlibabaCloudSnitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
super(connector, properties, SnitchUtils.parseDcAndRack(connector.apiCall(ZONE_NAME_QUERY_URL,
|
super(connector, SnitchUtils.parseDcAndRack(connector.apiCall(ZONE_NAME_QUERY_URL),
|
||||||
ImmutableMap.of()),
|
connector.getProperties().getDcSuffix()));
|
||||||
properties.getDcSuffix()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.apache.cassandra.locator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
|
import org.apache.cassandra.utils.JsonUtils;
|
||||||
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AzureSnitch will resolve datacenter and rack by calling {@code /metadata/instance/compute} endpoint returning
|
||||||
|
* the response in JSON format for API version {@code 2021-12-13}. The version of API is configurable via property
|
||||||
|
* {@code azure_api_version} in cassandra-rackdc.properties.
|
||||||
|
* <p>
|
||||||
|
* A datacenter is resolved from {@code location} field and a rack is resolved by looking into {@code zone} field first.
|
||||||
|
* When zone is not set, or it is empty string, it will look into {@code platformFaultDomain} field. Such resolved
|
||||||
|
* value is prepended by {@code rack-} string.
|
||||||
|
*/
|
||||||
|
public class AzureSnitch extends AbstractCloudMetadataServiceSnitch
|
||||||
|
{
|
||||||
|
static final String DEFAULT_METADATA_SERVICE_URL = "http://169.254.169.254";
|
||||||
|
static final String METADATA_QUERY_TEMPLATE = "/metadata/instance/compute?api-version=%s&format=json";
|
||||||
|
static final String METADATA_HEADER = "Metadata";
|
||||||
|
static final String API_VERSION_PROPERTY_KEY = "azure_api_version";
|
||||||
|
static final String DEFAULT_API_VERSION = "2021-12-13";
|
||||||
|
|
||||||
|
public AzureSnitch() throws IOException
|
||||||
|
{
|
||||||
|
this(new SnitchProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AzureSnitch(SnitchProperties properties) throws IOException
|
||||||
|
{
|
||||||
|
this(new DefaultCloudMetadataServiceConnector(properties.putIfAbsent(METADATA_URL_PROPERTY,
|
||||||
|
DEFAULT_METADATA_SERVICE_URL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AzureSnitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
|
{
|
||||||
|
super(connector, resolveDcAndRack(connector));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<String, String> resolveDcAndRack(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
|
{
|
||||||
|
String apiVersion = connector.getProperties().get(API_VERSION_PROPERTY_KEY, DEFAULT_API_VERSION);
|
||||||
|
String response = connector.apiCall(format(METADATA_QUERY_TEMPLATE, apiVersion), ImmutableMap.of(METADATA_HEADER, "true"));
|
||||||
|
JsonNode jsonNode = JsonUtils.JSON_OBJECT_MAPPER.readTree(response);
|
||||||
|
|
||||||
|
JsonNode location = jsonNode.get("location");
|
||||||
|
JsonNode zone = jsonNode.get("zone");
|
||||||
|
JsonNode platformFaultDomain = jsonNode.get("platformFaultDomain");
|
||||||
|
|
||||||
|
String datacenter;
|
||||||
|
String rack;
|
||||||
|
|
||||||
|
if (location == null || location.isNull() || location.asText().isEmpty())
|
||||||
|
datacenter = DEFAULT_DC;
|
||||||
|
else
|
||||||
|
datacenter = location.asText();
|
||||||
|
|
||||||
|
if (zone == null || zone.isNull() || zone.asText().isEmpty())
|
||||||
|
{
|
||||||
|
if (platformFaultDomain == null || platformFaultDomain.isNull() || platformFaultDomain.asText().isEmpty())
|
||||||
|
{
|
||||||
|
rack = DEFAULT_RACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rack = platformFaultDomain.asText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rack = zone.asText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair.create(datacenter + connector.getProperties().getDcSuffix(), "rack-" + rack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,11 +27,11 @@ import java.util.regex.Pattern;
|
||||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.cassandra.io.util.File;
|
import org.apache.cassandra.io.util.File;
|
||||||
import org.apache.cassandra.io.util.FileReader;
|
import org.apache.cassandra.io.util.FileReader;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
import org.apache.cassandra.utils.JVMStabilityInspector;
|
import org.apache.cassandra.utils.JVMStabilityInspector;
|
||||||
import org.apache.cassandra.utils.Pair;
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
import static org.apache.cassandra.locator.CloudstackSnitch.CloudstackConnector.ZONE_NAME_QUERY_URI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A snitch that assumes a Cloudstack Zone follows the typical convention
|
* A snitch that assumes a Cloudstack Zone follows the typical convention
|
||||||
|
|
@ -43,6 +43,8 @@ import static org.apache.cassandra.locator.CloudstackSnitch.CloudstackConnector.
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class CloudstackSnitch extends AbstractCloudMetadataServiceSnitch
|
public class CloudstackSnitch extends AbstractCloudMetadataServiceSnitch
|
||||||
{
|
{
|
||||||
|
static final String ZONE_NAME_QUERY_URI = "/latest/meta-data/availability-zone";
|
||||||
|
|
||||||
private static final String[] LEASE_FILES =
|
private static final String[] LEASE_FILES =
|
||||||
{
|
{
|
||||||
"file:///var/lib/dhcp/dhclient.eth0.leases",
|
"file:///var/lib/dhcp/dhclient.eth0.leases",
|
||||||
|
|
@ -56,26 +58,16 @@ public class CloudstackSnitch extends AbstractCloudMetadataServiceSnitch
|
||||||
|
|
||||||
public CloudstackSnitch(SnitchProperties snitchProperties) throws IOException
|
public CloudstackSnitch(SnitchProperties snitchProperties) throws IOException
|
||||||
{
|
{
|
||||||
this(snitchProperties, new CloudstackConnector(snitchProperties.putIfAbsent(METADATA_URL_PROPERTY, csMetadataEndpoint())));
|
this(new DefaultCloudMetadataServiceConnector(snitchProperties.putIfAbsent(METADATA_URL_PROPERTY, csMetadataEndpoint())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloudstackSnitch(SnitchProperties properties, AbstractCloudMetadataServiceConnector connector) throws IOException
|
public CloudstackSnitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
super(connector, properties, resolveDcAndRack(connector));
|
super(connector, resolveDcAndRack(connector));
|
||||||
logger.warn("{} is deprecated and not actively maintained. It will be removed in the next " +
|
logger.warn("{} is deprecated and not actively maintained. It will be removed in the next " +
|
||||||
"major version of Cassandra.", CloudstackSnitch.class.getName());
|
"major version of Cassandra.", CloudstackSnitch.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CloudstackConnector extends AbstractCloudMetadataServiceConnector
|
|
||||||
{
|
|
||||||
static final String ZONE_NAME_QUERY_URI = "/latest/meta-data/availability-zone";
|
|
||||||
|
|
||||||
protected CloudstackConnector(SnitchProperties properties)
|
|
||||||
{
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pair<String, String> resolveDcAndRack(AbstractCloudMetadataServiceConnector connector) throws IOException
|
private static Pair<String, String> resolveDcAndRack(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
String zone = connector.apiCall(ZONE_NAME_QUERY_URI);
|
String zone = connector.apiCall(ZONE_NAME_QUERY_URI);
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,12 @@ public class Ec2MultiRegionSnitch extends Ec2Snitch
|
||||||
|
|
||||||
public Ec2MultiRegionSnitch(SnitchProperties props) throws IOException, ConfigurationException
|
public Ec2MultiRegionSnitch(SnitchProperties props) throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
this(props, Ec2MetadataServiceConnector.create(props));
|
this(Ec2MetadataServiceConnector.create(props));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ec2MultiRegionSnitch(SnitchProperties props, AbstractCloudMetadataServiceConnector connector) throws IOException
|
Ec2MultiRegionSnitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
super(props, connector);
|
super(connector);
|
||||||
InetAddress localPublicAddress = InetAddress.getByName(connector.apiCall(PUBLIC_IP_QUERY));
|
InetAddress localPublicAddress = InetAddress.getByName(connector.apiCall(PUBLIC_IP_QUERY));
|
||||||
logger.info("EC2Snitch using publicIP as identifier: {}", localPublicAddress);
|
logger.info("EC2Snitch using publicIP as identifier: {}", localPublicAddress);
|
||||||
localPrivateAddress = connector.apiCall(PRIVATE_IP_QUERY);
|
localPrivateAddress = connector.apiCall(PRIVATE_IP_QUERY);
|
||||||
|
|
|
||||||
|
|
@ -63,22 +63,22 @@ public class Ec2Snitch extends AbstractCloudMetadataServiceSnitch
|
||||||
|
|
||||||
public Ec2Snitch(SnitchProperties props) throws IOException, ConfigurationException
|
public Ec2Snitch(SnitchProperties props) throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
this(props, Ec2MetadataServiceConnector.create(props));
|
this(Ec2MetadataServiceConnector.create(props));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ec2Snitch(SnitchProperties props, AbstractCloudMetadataServiceConnector connector) throws IOException
|
Ec2Snitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
super(connector, props, getDcAndRack(props, connector));
|
super(connector, getDcAndRack(connector));
|
||||||
usingLegacyNaming = isUsingLegacyNaming(props);
|
usingLegacyNaming = isUsingLegacyNaming(connector.getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pair<String, String> getDcAndRack(SnitchProperties props, AbstractCloudMetadataServiceConnector connector) throws IOException
|
private static Pair<String, String> getDcAndRack(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
String az = connector.apiCall(ZONE_NAME_QUERY);
|
String az = connector.apiCall(ZONE_NAME_QUERY);
|
||||||
|
|
||||||
// if using the full naming scheme, region name is created by removing letters from the
|
// if using the full naming scheme, region name is created by removing letters from the
|
||||||
// end of the availability zone and zone is the full zone name
|
// end of the availability zone and zone is the full zone name
|
||||||
boolean usingLegacyNaming = isUsingLegacyNaming(props);
|
boolean usingLegacyNaming = isUsingLegacyNaming(connector.getProperties());
|
||||||
String region;
|
String region;
|
||||||
String localDc;
|
String localDc;
|
||||||
String localRack;
|
String localRack;
|
||||||
|
|
@ -101,7 +101,7 @@ public class Ec2Snitch extends AbstractCloudMetadataServiceSnitch
|
||||||
localRack = az;
|
localRack = az;
|
||||||
}
|
}
|
||||||
|
|
||||||
localDc = region.concat(props.getDcSuffix());
|
localDc = region.concat(connector.getProperties().getDcSuffix());
|
||||||
|
|
||||||
return Pair.create(localDc, localRack);
|
return Pair.create(localDc, localRack);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ public class GoogleCloudSnitch extends AbstractCloudMetadataServiceSnitch
|
||||||
|
|
||||||
public GoogleCloudSnitch(SnitchProperties properties) throws IOException
|
public GoogleCloudSnitch(SnitchProperties properties) throws IOException
|
||||||
{
|
{
|
||||||
this(properties, new DefaultCloudMetadataServiceConnector(properties.putIfAbsent(METADATA_URL_PROPERTY,
|
this(new DefaultCloudMetadataServiceConnector(properties.putIfAbsent(METADATA_URL_PROPERTY,
|
||||||
DEFAULT_METADATA_SERVICE_URL)));
|
DEFAULT_METADATA_SERVICE_URL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GoogleCloudSnitch(SnitchProperties properties, AbstractCloudMetadataServiceConnector connector) throws IOException
|
public GoogleCloudSnitch(AbstractCloudMetadataServiceConnector connector) throws IOException
|
||||||
{
|
{
|
||||||
super(connector, properties, SnitchUtils.parseDcAndRack(connector.apiCall(ZONE_NAME_QUERY_URL,
|
super(connector, SnitchUtils.parseDcAndRack(connector.apiCall(ZONE_NAME_QUERY_URL,
|
||||||
ImmutableMap.of("Metadata-Flavor", "Google")),
|
ImmutableMap.of("Metadata-Flavor", "Google")),
|
||||||
properties.getDcSuffix()));
|
connector.getProperties().getDcSuffix()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ package org.apache.cassandra.locator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
@ -33,16 +32,19 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.cassandra.gms.ApplicationState;
|
import org.apache.cassandra.gms.ApplicationState;
|
||||||
import org.apache.cassandra.gms.Gossiper;
|
import org.apache.cassandra.gms.Gossiper;
|
||||||
import org.apache.cassandra.gms.VersionedValue;
|
import org.apache.cassandra.gms.VersionedValue;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
import org.apache.cassandra.service.StorageService;
|
import org.apache.cassandra.service.StorageService;
|
||||||
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
||||||
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
||||||
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
||||||
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
|
import static org.apache.cassandra.locator.AlibabaCloudSnitch.DEFAULT_METADATA_SERVICE_URL;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyMap;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class AlibabaCloudSnitchTest
|
public class AlibabaCloudSnitchTest
|
||||||
{
|
{
|
||||||
|
|
@ -66,10 +68,12 @@ public class AlibabaCloudSnitchTest
|
||||||
{
|
{
|
||||||
az = "cn-hangzhou-f";
|
az = "cn-hangzhou-f";
|
||||||
|
|
||||||
AbstractCloudMetadataServiceConnector mock = mock(AbstractCloudMetadataServiceConnector.class);
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
when(mock.apiCall(any(), anyMap())).thenReturn(az);
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, DEFAULT_METADATA_SERVICE_URL))));
|
||||||
|
|
||||||
AlibabaCloudSnitch snitch = new AlibabaCloudSnitch(new SnitchProperties(new Properties()), mock);
|
doReturn(az).when(spiedConnector).apiCall(any());
|
||||||
|
|
||||||
|
AlibabaCloudSnitch snitch = new AlibabaCloudSnitch(spiedConnector);
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
||||||
|
|
||||||
|
|
@ -90,11 +94,12 @@ public class AlibabaCloudSnitchTest
|
||||||
public void testNewRegions() throws IOException, ConfigurationException
|
public void testNewRegions() throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
az = "us-east-1a";
|
az = "us-east-1a";
|
||||||
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, DEFAULT_METADATA_SERVICE_URL))));
|
||||||
|
|
||||||
AbstractCloudMetadataServiceConnector mock = mock(AbstractCloudMetadataServiceConnector.class);
|
doReturn(az).when(spiedConnector).apiCall(any());
|
||||||
when(mock.apiCall(any(), anyMap())).thenReturn(az);
|
|
||||||
|
|
||||||
AlibabaCloudSnitch snitch = new AlibabaCloudSnitch(new SnitchProperties(new Properties()), mock);
|
AlibabaCloudSnitch snitch = new AlibabaCloudSnitch(spiedConnector);
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
assertEquals("us-east", snitch.getDatacenter(local));
|
assertEquals("us-east", snitch.getDatacenter(local));
|
||||||
assertEquals("1a", snitch.getRack(local));
|
assertEquals("1a", snitch.getRack(local));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.apache.cassandra.locator;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.github.tomakehurst.wiremock.junit.WireMockRule;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
|
|
||||||
|
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||||
|
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
|
||||||
|
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||||
|
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||||
|
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
|
import static org.apache.cassandra.locator.AzureSnitch.API_VERSION_PROPERTY_KEY;
|
||||||
|
import static org.apache.cassandra.locator.AzureSnitch.METADATA_HEADER;
|
||||||
|
import static org.apache.cassandra.locator.AzureSnitch.METADATA_QUERY_TEMPLATE;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class AzureConnectorMockingTest
|
||||||
|
{
|
||||||
|
@Rule
|
||||||
|
public final WireMockRule service = new WireMockRule(wireMockConfig().bindAddress("127.0.0.1").port(8080));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnector() throws Throwable
|
||||||
|
{
|
||||||
|
String RESPONSE = "{\"location\": \"PolandCentral\", \"zone\": \"1\", \"platformFaultDomain\": \"5\"}";
|
||||||
|
|
||||||
|
service.stubFor(get(urlEqualTo(format(METADATA_QUERY_TEMPLATE, "2021-12-13")))
|
||||||
|
.withHeader(METADATA_HEADER, equalTo("true"))
|
||||||
|
.willReturn(aResponse().withBody(RESPONSE)
|
||||||
|
.withStatus(200)
|
||||||
|
.withHeader("Content-Type", "application/json; charset=utf-8")
|
||||||
|
.withHeader("Content-Length", String.valueOf(RESPONSE.getBytes(UTF_8).length))));
|
||||||
|
|
||||||
|
Properties p = new Properties();
|
||||||
|
p.setProperty(METADATA_URL_PROPERTY, "http://127.0.0.1:8080");
|
||||||
|
|
||||||
|
SnitchProperties snitchProperties = new SnitchProperties(p);
|
||||||
|
AzureSnitch azureSnitch = new AzureSnitch(new DefaultCloudMetadataServiceConnector(snitchProperties));
|
||||||
|
|
||||||
|
assertEquals("rack-1", azureSnitch.getLocalRack());
|
||||||
|
assertEquals("PolandCentral", azureSnitch.getLocalDatacenter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingZone() throws Throwable
|
||||||
|
{
|
||||||
|
String RESPONSE = "{\"location\": \"PolandCentral\", \"zone\": \"\", \"platformFaultDomain\": \"5\"}";
|
||||||
|
|
||||||
|
service.stubFor(get(urlEqualTo(format(METADATA_QUERY_TEMPLATE, "2021-12-14")))
|
||||||
|
.withHeader(METADATA_HEADER, equalTo("true"))
|
||||||
|
.willReturn(aResponse().withBody(RESPONSE)
|
||||||
|
.withStatus(200)
|
||||||
|
.withHeader("Content-Type", "application/json; charset=utf-8")
|
||||||
|
.withHeader("Content-Length", String.valueOf(RESPONSE.getBytes(UTF_8).length))));
|
||||||
|
|
||||||
|
Properties p = new Properties();
|
||||||
|
p.setProperty(METADATA_URL_PROPERTY, "http://127.0.0.1:8080");
|
||||||
|
p.setProperty(API_VERSION_PROPERTY_KEY, "2021-12-14");
|
||||||
|
|
||||||
|
SnitchProperties snitchProperties = new SnitchProperties(p);
|
||||||
|
AzureSnitch azureSnitch = new AzureSnitch(new DefaultCloudMetadataServiceConnector(snitchProperties));
|
||||||
|
|
||||||
|
assertEquals("rack-5", azureSnitch.getLocalRack());
|
||||||
|
assertEquals("PolandCentral", azureSnitch.getLocalDatacenter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,6 @@ package org.apache.cassandra.locator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
@ -34,15 +33,18 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.cassandra.gms.ApplicationState;
|
import org.apache.cassandra.gms.ApplicationState;
|
||||||
import org.apache.cassandra.gms.Gossiper;
|
import org.apache.cassandra.gms.Gossiper;
|
||||||
import org.apache.cassandra.gms.VersionedValue;
|
import org.apache.cassandra.gms.VersionedValue;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
import org.apache.cassandra.service.StorageService;
|
import org.apache.cassandra.service.StorageService;
|
||||||
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
||||||
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
||||||
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
||||||
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
public class CloudstackSnitchTest
|
public class CloudstackSnitchTest
|
||||||
{
|
{
|
||||||
|
|
@ -65,10 +67,13 @@ public class CloudstackSnitchTest
|
||||||
public void testRacks() throws IOException, ConfigurationException
|
public void testRacks() throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
az = "ch-gva-1";
|
az = "ch-gva-1";
|
||||||
CloudstackSnitch.CloudstackConnector mock = mock(CloudstackSnitch.CloudstackConnector.class);
|
|
||||||
when(mock.apiCall(any())).thenReturn(az);
|
|
||||||
|
|
||||||
CloudstackSnitch snitch = new CloudstackSnitch(new SnitchProperties(new Properties()), mock);
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, "http://127.0.0.1"))));
|
||||||
|
|
||||||
|
doReturn(az).when(spiedConnector).apiCall(any());
|
||||||
|
|
||||||
|
CloudstackSnitch snitch = new CloudstackSnitch(spiedConnector);
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
||||||
|
|
||||||
|
|
@ -88,15 +93,19 @@ public class CloudstackSnitchTest
|
||||||
@Test
|
@Test
|
||||||
public void testNewRegions() throws IOException, ConfigurationException
|
public void testNewRegions() throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
az = "ch-gva-1";
|
az = "us-east-1a";
|
||||||
CloudstackSnitch.CloudstackConnector mock = mock(CloudstackSnitch.CloudstackConnector.class);
|
|
||||||
when(mock.apiCall(any())).thenReturn(az);
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
CloudstackSnitch snitch = new CloudstackSnitch(new SnitchProperties(new Properties()), mock);
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, "http://127.0.0.1"))));
|
||||||
|
|
||||||
|
doReturn(az).when(spiedConnector).apiCall(any());
|
||||||
|
|
||||||
|
CloudstackSnitch snitch = new CloudstackSnitch(spiedConnector);
|
||||||
|
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
|
|
||||||
assertEquals("ch-gva", snitch.getDatacenter(local));
|
assertEquals("us-east", snitch.getDatacenter(local));
|
||||||
assertEquals("1", snitch.getRack(local));
|
assertEquals("1a", snitch.getRack(local));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
|
@ -48,7 +47,10 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class Ec2SnitchTest
|
public class Ec2SnitchTest
|
||||||
|
|
@ -85,51 +87,55 @@ public class Ec2SnitchTest
|
||||||
public void testLegacyRac() throws Exception
|
public void testLegacyRac() throws Exception
|
||||||
{
|
{
|
||||||
Ec2MetadataServiceConnector connectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector connectorMock = mock(Ec2MetadataServiceConnector.class);
|
||||||
when(connectorMock.apiCall(anyString())).thenReturn("us-east-1d");
|
doReturn("us-east-1d").when(connectorMock).apiCall(anyString());
|
||||||
Ec2Snitch snitch = new Ec2Snitch(legacySnitchProps, connectorMock);
|
doReturn(legacySnitchProps).when(connectorMock).getProperties();
|
||||||
|
Ec2Snitch snitch = new Ec2Snitch(connectorMock);
|
||||||
testLegacyRacInternal(snitch);
|
testLegacyRacInternal(snitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultiregionLegacyRac() throws Exception
|
public void testMultiregionLegacyRac() throws Exception
|
||||||
{
|
{
|
||||||
Ec2MetadataServiceConnector multiRegionConnectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector spy = spy(Ec2MetadataServiceConnector.create(legacySnitchProps));
|
||||||
when(multiRegionConnectorMock.apiCall(anyString())).then((Answer<String>) invocation -> {
|
doReturn(legacySnitchProps).when(spy).getProperties();
|
||||||
|
doAnswer((Answer<String>) invocation -> {
|
||||||
String query = invocation.getArgument(0);
|
String query = invocation.getArgument(0);
|
||||||
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-1d";
|
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-1d";
|
||||||
});
|
}).when(spy).apiCall(anyString());
|
||||||
|
|
||||||
Ec2Snitch snitch = new Ec2MultiRegionSnitch(legacySnitchProps, multiRegionConnectorMock);
|
Ec2Snitch snitch = new Ec2MultiRegionSnitch(spy);
|
||||||
testLegacyRacInternal(snitch);
|
testLegacyRacInternal(snitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLegacyNewRegions() throws Exception
|
public void testLegacyNewRegions() throws Exception
|
||||||
{
|
{
|
||||||
Ec2MetadataServiceConnector connectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector spy = spy(Ec2MetadataServiceConnector.create(legacySnitchProps));
|
||||||
when(connectorMock.apiCall(anyString())).thenReturn("us-east-2d");
|
doReturn(legacySnitchProps).when(spy).getProperties();
|
||||||
testLegacyNewRegionsInternal(new Ec2Snitch(legacySnitchProps, connectorMock));
|
doReturn("us-east-2d").when(spy).apiCall(anyString());
|
||||||
|
testLegacyNewRegionsInternal(new Ec2Snitch(spy));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLegacyMultiRegionNewRegions() throws Exception
|
public void testLegacyMultiRegionNewRegions() throws Exception
|
||||||
{
|
{
|
||||||
Ec2MetadataServiceConnector multiRegionConnectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector spy = spy(Ec2MetadataServiceConnector.create(legacySnitchProps));
|
||||||
when(multiRegionConnectorMock.apiCall(anyString())).then((Answer<String>) invocation -> {
|
doReturn(legacySnitchProps).when(spy).getProperties();
|
||||||
|
doAnswer((Answer<String>) invocation -> {
|
||||||
String query = invocation.getArgument(0);
|
String query = invocation.getArgument(0);
|
||||||
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-2d";
|
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-2d";
|
||||||
});
|
}).when(spy).apiCall(anyString());
|
||||||
|
|
||||||
testLegacyNewRegionsInternal(new Ec2MultiRegionSnitch(legacySnitchProps, multiRegionConnectorMock));
|
testLegacyNewRegionsInternal(new Ec2MultiRegionSnitch(spy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFullNamingScheme() throws Exception
|
public void testFullNamingScheme() throws Exception
|
||||||
{
|
{
|
||||||
Ec2MetadataServiceConnector connectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector connectorMock = mock(Ec2MetadataServiceConnector.class);
|
||||||
when(connectorMock.apiCall(anyString())).thenReturn("us-east-2d");
|
when(connectorMock.apiCall(anyString())).thenReturn("us-east-2d");
|
||||||
Ec2Snitch snitch = new Ec2Snitch(new SnitchProperties(new Properties()), connectorMock);
|
when(connectorMock.getProperties()).thenReturn(new SnitchProperties());
|
||||||
|
Ec2Snitch snitch = new Ec2Snitch(connectorMock);
|
||||||
|
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
|
|
||||||
|
|
@ -137,6 +143,7 @@ public class Ec2SnitchTest
|
||||||
assertEquals("us-east-2d", snitch.getRack(local));
|
assertEquals("us-east-2d", snitch.getRack(local));
|
||||||
|
|
||||||
Ec2MetadataServiceConnector multiRegionConnectorMock = mock(Ec2MetadataServiceConnector.class);
|
Ec2MetadataServiceConnector multiRegionConnectorMock = mock(Ec2MetadataServiceConnector.class);
|
||||||
|
when(connectorMock.getProperties()).thenReturn(new SnitchProperties());
|
||||||
when(multiRegionConnectorMock.apiCall(anyString())).then((Answer<String>) invocation -> {
|
when(multiRegionConnectorMock.apiCall(anyString())).then((Answer<String>) invocation -> {
|
||||||
String query = invocation.getArgument(0);
|
String query = invocation.getArgument(0);
|
||||||
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-2d";
|
return (PUBLIC_IP_QUERY.equals(query) || PRIVATE_IP_QUERY.equals(query)) ? "127.0.0.1" : "us-east-2d";
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ package org.apache.cassandra.locator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
@ -35,16 +34,20 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.cassandra.gms.ApplicationState;
|
import org.apache.cassandra.gms.ApplicationState;
|
||||||
import org.apache.cassandra.gms.Gossiper;
|
import org.apache.cassandra.gms.Gossiper;
|
||||||
import org.apache.cassandra.gms.VersionedValue;
|
import org.apache.cassandra.gms.VersionedValue;
|
||||||
|
import org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.DefaultCloudMetadataServiceConnector;
|
||||||
import org.apache.cassandra.service.StorageService;
|
import org.apache.cassandra.service.StorageService;
|
||||||
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
import static org.apache.cassandra.ServerTestUtils.cleanup;
|
||||||
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
import static org.apache.cassandra.ServerTestUtils.mkdirs;
|
||||||
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
import static org.apache.cassandra.config.CassandraRelevantProperties.GOSSIP_DISABLE_THREAD_VALIDATION;
|
||||||
|
import static org.apache.cassandra.locator.AbstractCloudMetadataServiceConnector.METADATA_URL_PROPERTY;
|
||||||
|
import static org.apache.cassandra.locator.AlibabaCloudSnitch.DEFAULT_METADATA_SERVICE_URL;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyMap;
|
import static org.mockito.ArgumentMatchers.anyMap;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
public class GoogleCloudSnitchTest
|
public class GoogleCloudSnitchTest
|
||||||
{
|
{
|
||||||
|
|
@ -66,10 +69,12 @@ public class GoogleCloudSnitchTest
|
||||||
{
|
{
|
||||||
String az = "us-central1-a";
|
String az = "us-central1-a";
|
||||||
|
|
||||||
AbstractCloudMetadataServiceConnector mock = mock(AbstractCloudMetadataServiceConnector.class);
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
when(mock.apiCall(any(), anyMap())).thenReturn(az);
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, DEFAULT_METADATA_SERVICE_URL))));
|
||||||
|
|
||||||
GoogleCloudSnitch snitch = new GoogleCloudSnitch(new SnitchProperties(new Properties()), mock);
|
doReturn(az).when(spiedConnector).apiCall(any(), anyMap());
|
||||||
|
|
||||||
|
GoogleCloudSnitch snitch = new GoogleCloudSnitch(spiedConnector);
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
InetAddressAndPort nonlocal = InetAddressAndPort.getByName("127.0.0.7");
|
||||||
|
|
||||||
|
|
@ -90,10 +95,13 @@ public class GoogleCloudSnitchTest
|
||||||
public void testNewRegions() throws IOException, ConfigurationException
|
public void testNewRegions() throws IOException, ConfigurationException
|
||||||
{
|
{
|
||||||
String az = "asia-east1-a";
|
String az = "asia-east1-a";
|
||||||
AbstractCloudMetadataServiceConnector mock = mock(AbstractCloudMetadataServiceConnector.class);
|
|
||||||
when(mock.apiCall(any(), anyMap())).thenReturn(az);
|
|
||||||
|
|
||||||
GoogleCloudSnitch snitch = new GoogleCloudSnitch(new SnitchProperties(new Properties()), mock);
|
DefaultCloudMetadataServiceConnector spiedConnector = spy(new DefaultCloudMetadataServiceConnector(
|
||||||
|
new SnitchProperties(Pair.create(METADATA_URL_PROPERTY, DEFAULT_METADATA_SERVICE_URL))));
|
||||||
|
|
||||||
|
doReturn(az).when(spiedConnector).apiCall(any(), anyMap());
|
||||||
|
|
||||||
|
GoogleCloudSnitch snitch = new GoogleCloudSnitch(spiedConnector);
|
||||||
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
InetAddressAndPort local = InetAddressAndPort.getByName("127.0.0.1");
|
||||||
assertEquals("asia-east1", snitch.getDatacenter(local));
|
assertEquals("asia-east1", snitch.getDatacenter(local));
|
||||||
assertEquals("a", snitch.getRack(local));
|
assertEquals("a", snitch.getRack(local));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue