/*
* Copyright 2013-2017 the original author or authors.
*
* 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 org.springframework.cassandra.test.integration.core.cql.generator;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cassandra.core.cql.CqlStringUtils;
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
import org.springframework.cassandra.core.keyspace.TableDescriptor;
import org.springframework.cassandra.core.keyspace.TableOption;
import com.datastax.driver.core.ColumnMetadata;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.TableMetadata;
import com.datastax.driver.core.TableOptionsMetadata;
/**
* @author Matthew T. Adams
* @author David Webb
* @author Alex Shvid
* @author Antoine Toulme
*/
public class CqlTableSpecificationAssertions {
private static final Logger log = LoggerFactory.getLogger(CqlTableSpecificationAssertions.class);
public static double DELTA = 1e-6; // delta for comparisons of doubles
public static void assertTable(TableDescriptor expected, String keyspace, Session session) {
TableMetadata tmd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
.getTable(expected.getName().getUnquoted()); // TODO: talk to Datastax about unquoting
assertThat(expected.getName().getUnquoted()).isEqualTo(tmd.getName()); // TODO: talk to Datastax
assertPartitionKeyColumns(expected, tmd);
assertPrimaryKeyColumns(expected, tmd);
assertColumns(expected.getColumns(), tmd.getColumns());
assertOptions(expected.getOptions(), tmd.getOptions());
}
public static void assertNoTable(DropTableSpecification expected, String keyspace, Session session) {
TableMetadata tmd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
.getTable(expected.getName().toCql());
assertThat(tmd).isNull();
}
public static void assertPartitionKeyColumns(TableDescriptor expected, TableMetadata actual) {
assertColumns(expected.getPartitionKeyColumns(), actual.getPartitionKey());
}
public static void assertPrimaryKeyColumns(TableDescriptor expected, TableMetadata actual) {
assertColumns(expected.getPrimaryKeyColumns(), actual.getPrimaryKey());
}
public static void assertOptions(Map<String, Object> expected, TableOptionsMetadata actual) {
for (String key : expected.keySet()) {
log.info(key + " -> " + expected.get(key));
Object value = expected.get(key);
TableOption tableOption = getTableOptionFor(key.toUpperCase());
if (tableOption == null && key.equalsIgnoreCase(TableOption.COMPACT_STORAGE.getName())) {
// TODO: figure out how to tell if COMPACT STORAGE was used
continue;
}
assertOption(tableOption, key, value, getOptionFor(tableOption, tableOption.getType(), actual));
}
}
@SuppressWarnings({ "unchecked", "incomplete-switch" })
public static void assertOption(TableOption tableOption, String key, Object expected, Object actual) {
if (tableOption == null) { // then this is a string-only or unknown value
key.equalsIgnoreCase(actual.toString()); // TODO: determine if this is the right test
}
switch (tableOption) {
case BLOOM_FILTER_FP_CHANCE:
case READ_REPAIR_CHANCE:
case DCLOCAL_READ_REPAIR_CHANCE:
assertThat((Double) expected).isCloseTo((Double) actual, offset(DELTA));
return;
case CACHING:
assertCaching((Map<String, Object>) expected, (Map<String, String>) actual);
return;
case COMPACTION:
assertCompaction((Map<String, Object>) expected, (Map<String, String>) actual);
return;
case COMPRESSION:
assertCompression((Map<String, Object>) expected, (Map<String, String>) actual);
return;
}
log.info(actual.getClass().getName());
assertThat(
tableOption.quotesValue() && !(actual instanceof CharSequence) ? CqlStringUtils.singleQuote(actual) : actual)
.isEqualTo(expected);
}
public static void assertCaching(Map<String, Object> expected, Map<String, String> actual) {
// TODO
}
public static void assertCompaction(Map<String, Object> expected, Map<String, String> actual) {
// TODO
}
public static void assertCompression(Map<String, Object> expected, Map<String, String> actual) {
// TODO
}
public static TableOption getTableOptionFor(String key) {
try {
return TableOption.valueOf(key);
} catch (IllegalArgumentException x) {
return null;
}
}
@SuppressWarnings("unchecked")
public static <T> T getOptionFor(TableOption option, Class<?> type, TableOptionsMetadata options) {
switch (option) {
case BLOOM_FILTER_FP_CHANCE:
return (T) (Double) options.getBloomFilterFalsePositiveChance();
case CACHING:
return (T) options.getCaching();
case COMMENT:
return (T) CqlStringUtils.singleQuote(options.getComment());
case COMPACTION:
return (T) options.getCompaction();
case COMPACT_STORAGE:
throw new Error(); // TODO: figure out
case COMPRESSION:
return (T) options.getCompression();
case DCLOCAL_READ_REPAIR_CHANCE:
return (T) (Double) options.getLocalReadRepairChance();
case GC_GRACE_SECONDS:
return (T) new Long(options.getGcGraceInSeconds());
case READ_REPAIR_CHANCE:
return (T) (Double) options.getReadRepairChance();
}
return null;
}
public static void assertColumns(List<ColumnSpecification> expected, List<ColumnMetadata> actual) {
for (int i = 0; i < expected.size(); i++) {
ColumnSpecification expectedColumn = expected.get(i);
ColumnMetadata actualColumn = actual.get(i);
assertColumn(expectedColumn, actualColumn);
}
}
public static void assertColumn(ColumnSpecification expected, ColumnMetadata actual) {
assertThat(expected.getName().toCql()).isEqualTo(actual.getName()); // TODO: expected.getName().getUnquoted()?
assertThat(expected.getType()).isEqualTo(actual.getType());
}
}