/* * 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 org.apache.log4j.Level; import org.apache.log4j.Logger; import org.testng.annotations.Test; import java.net.InetAddress; import static com.datastax.driver.core.Assertions.assertThat; import static com.datastax.driver.core.TestUtils.nonQuietClusterCloseOptions; public class HostMetadataIntegrationTest { /** * Validates that {@link Host#getDseVersion()} and {@link Host#getDseWorkload()} return values defined in * the <code>dse_version</code> and <code>workload</code> columns if they are present in <code>system.local</code> * or <code>system.peers</code> otherwise they return null. * * @test_category host:metadata * @jira_ticket JAVA-1042 */ @Test(groups = "short") public void should_parse_dse_workload_and_version_if_available() { // given: A 5 node cluster with all nodes having a workload and dse_version except node 2. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(5) .forcePeerInfo(1, 1, "workload", "Analytics") .forcePeerInfo(1, 1, "dse_version", "4.8.4") .forcePeerInfo(1, 3, "workload", "Solr") .forcePeerInfo(1, 3, "dse_version", "4.8.4") .forcePeerInfo(1, 4, "workload", "Cassandra") .forcePeerInfo(1, 4, "dse_version", "4.8.4") .forcePeerInfo(1, 5, "workload", "AmazingNewFeature") .forcePeerInfo(1, 5, "dse_version", "5.0.0") .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: All nodes except node 2 should have a workload and dse version. assertThat(cluster).host(1).hasWorkload("Analytics").hasDseVersion(VersionNumber.parse("4.8.4")); assertThat(cluster).host(2).hasNoWorkload().hasNoDseVersion(); assertThat(cluster).host(3).hasWorkload("Solr").hasDseVersion(VersionNumber.parse("4.8.4")); assertThat(cluster).host(4).hasWorkload("Cassandra").hasDseVersion(VersionNumber.parse("4.8.4")); assertThat(cluster).host(5).hasWorkload("AmazingNewFeature").hasDseVersion(VersionNumber.parse("5.0.0")); } finally { cluster.close(); scassandraCluster.stop(); } } /** * Validates that {@link Host#getDseVersion()} and {@link Host#getDseWorkload()} return null if * the <code>dse_version</code> and <code>workload</code> columns are not present in <code>system.local</code> * for the control host. * * @test_category host:metadata * @jira_ticket JAVA-1042 */ @Test(groups = "short") public void should_not_parse_dse_workload_and_version_if_not_present_in_local_table() { // given: A cluster with node 1 (control host) not having a workload or dse_version set, and node 2 with those // columns set. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(2) .forcePeerInfo(1, 2, "workload", "Analytics") .forcePeerInfo(1, 2, "dse_version", "4.8.4") .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: // - node 1 should have no workload or dse version. // - node 2 should have a workload and a dse version. assertThat(cluster).host(1).hasNoWorkload().hasNoDseVersion(); assertThat(cluster).host(2).hasWorkload("Analytics").hasDseVersion(VersionNumber.parse("4.8.4")); } finally { cluster.close(); scassandraCluster.stop(); } } /** * Validates that if <code>dse_version</code> column is a non-version value in <code>system.local</code> or * <code>system.peers</code> that a warning is logged and {@link Host#getDseVersion()} returns null. * * @test_category host:metadata * @jira_ticket JAVA-1042 */ @Test(groups = "short") public void should_log_warning_when_invalid_version_used_for_dse_version() { // given: A cluster with a node that has an invalid version for dse_version in system.local. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(1) .forcePeerInfo(1, 1, "workload", "Analytics") .forcePeerInfo(1, 1, "dse_version", "Invalid Version!") .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); MemoryAppender logs = new MemoryAppender(); Logger logger = Logger.getLogger(Host.class); Level originalLoggerLevel = logger.getLevel(); logger.setLevel(Level.WARN); logger.addAppender(logs); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: dse version for that host should not be set and a warning shall be logged. assertThat(logs.get()) .contains("Error parsing DSE version Invalid Version!. This shouldn't have happened"); assertThat(cluster).host(1).hasNoDseVersion().hasWorkload("Analytics"); } finally { logger.removeAppender(logs); logger.setLevel(originalLoggerLevel); cluster.close(); scassandraCluster.stop(); } } /** * Validates that {@link Host#isDseGraphEnabled()} returns the value defined in the <code>graph</code> columns if * it is present in <code>system.local</code> or <code>system.peers</code> otherwise it returns false. * * @test_category host:metadata * @jira_ticket JAVA-1171 */ @Test(groups = "short") public void should_parse_dse_graph_if_available() { // given: A 3 node cluster with all nodes having a graph value except node 2. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(3) .forcePeerInfo(1, 1, "graph", true) .forcePeerInfo(1, 3, "graph", false) .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: // - node 1 should have graph. // - node 2 and node 3 should not have graph. assertThat(cluster).host(1).hasDseGraph(); assertThat(cluster).host(2).hasNoDseGraph(); assertThat(cluster).host(3).hasNoDseGraph(); } finally { cluster.close(); scassandraCluster.stop(); } } /** * Validates that {@link Host#isDseGraphEnabled()} returns false if the <code>graph</code> column is not present * in <code>system.local</code> for the control host. * * @test_category host:metadata * @jira_ticket JAVA-1171 */ @Test(groups = "short") public void should_not_parse_dse_graph_if_not_present_in_local_table() { // given: A cluster with node 1 (control host) not having graph set, and node 2 with it set. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(2) .forcePeerInfo(1, 2, "graph", true) .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: // - node 1 should have no graph. // - node 2 should have graph. assertThat(cluster).host(1).hasNoDseGraph(); assertThat(cluster).host(2).hasDseGraph(); } finally { cluster.close(); scassandraCluster.stop(); } } /** * Validates that {@link Host#getBroadcastAddress()} is set for all hosts (control host or not) in the default * case of a cluster, as the broadcast address is derived from <code>broadcast_address</code> in * <code>system.local</code> and <code>peer</code> in <code>system.peers</code>. * * @test_category host:metadata * @jira_ticket JAVA-1035 */ @Test(groups = "short") public void should_set_broadcast_address_for_all_nodes() { // given: A cluster with 3 nodes. ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(3) .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { scassandraCluster.init(); // when: initializing a cluster instance. cluster.init(); // then: broadcast address should be set for each host: // - broadcast_address is used for system.local and is always present, so control host should have it. // - peer column is used for system.peers to resolve broadcast address and is always present. for (int i = 1; i <= scassandraCluster.nodes().size(); i++) { assertThat(cluster).host(i).hasBroadcastAddress(TestUtils.addressOfNode(i)); } } finally { cluster.close(); scassandraCluster.stop(); } } /** * Validates that {@link Host#getListenAddress()} is set for a host if and only if the <code>listen_address</code> * column is present and set in the <code>system.peers</code> table or if the host is the control host. * * @test_category host:metadata * @jira_ticket JAVA-1035 */ @Test(groups = "short") public void should_set_listen_address_if_available() { // given: A Cluster with 3 nodes and node 2 being configured with a listen address in its peers table. InetAddress listenAddress = TestUtils.addressOfNode(10); ScassandraCluster scassandraCluster = ScassandraCluster.builder() .withIpPrefix(TestUtils.IP_PREFIX) .withNodes(3) .forcePeerInfo(1, 2, "listen_address", listenAddress) .build(); Cluster cluster = Cluster.builder() .addContactPoints(scassandraCluster.address(1).getAddress()) .withPort(scassandraCluster.getBinaryPort()) .withNettyOptions(nonQuietClusterCloseOptions) .build(); try { // when: initializing a cluster instance. scassandraCluster.init(); cluster.init(); // then: listen address should be set appropriate for each host: // - Control Host will always have a listen address (listen_address should always be present). assertThat(cluster).host(1).hasListenAddress(TestUtils.addressOfNode(1)); // - Host 2 should have a listen address since we provided one. assertThat(cluster).host(2).hasListenAddress(listenAddress); // - Host 3 should have no listen address as it wasn't provided. assertThat(cluster).host(3).hasNoListenAddress(); } finally { cluster.close(); scassandraCluster.stop(); } } }