/*
* Copyright (C) 2012-2015 DataStax Inc.
*
* Licensed 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 com.datastax.driver.core;
import com.datastax.driver.core.policies.Policies;
import com.datastax.driver.core.policies.WhiteListPolicy;
import com.google.common.collect.Lists;
import org.testng.annotations.Test;
import java.net.InetSocketAddress;
import static com.datastax.driver.core.CreateCCM.TestMode.PER_METHOD;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
/**
* Tests the behavior of the driver when some hosts have no rpc_address in the control host's system tables (JAVA-428).
* <p/>
* This can happen because of gossip bugs. We want to ignore these hosts because this is most likely indicative of an error state.
*/
@CreateCCM(PER_METHOD)
@CCMConfig(numberOfNodes = 2, dirtiesContext = true, createCluster = false)
public class MissingRpcAddressTest extends CCMTestsSupport {
@Test(groups = "short")
public void testMissingRpcAddressAtStartup() throws Exception {
deleteNode2RpcAddressFromNode1();
// Use only one contact point to make sure that the control connection is on node1
Cluster cluster = register(Cluster.builder()
.addContactPoints(getContactPoints().get(0))
.withPort(ccm().getBinaryPort())
.build());
cluster.connect();
// Since node2's RPC address is unknown on our control host, it should have been ignored
assertEquals(cluster.getMetrics().getConnectedToHosts().getValue().intValue(), 1);
assertNull(cluster.getMetadata().getHost(getContactPointsWithPorts().get(1)));
}
// Artificially modify the system tables to simulate the missing rpc_address.
private void deleteNode2RpcAddressFromNode1() throws Exception {
InetSocketAddress firstHost = ccm().addressOfNode(1);
Cluster cluster = register(Cluster.builder()
.addContactPoints(firstHost.getAddress())
.withPort(ccm().getBinaryPort())
// ensure we will only connect to node1
.withLoadBalancingPolicy(new WhiteListPolicy(Policies.defaultLoadBalancingPolicy(),
Lists.newArrayList(firstHost)))
.build());
Session session = cluster.connect();
String deleteStmt = String.format("DELETE rpc_address FROM system.peers WHERE peer = '%s'",
ccm().addressOfNode(2).getHostName());
session.execute(deleteStmt);
session.close();
cluster.close();
}
}