You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2014/01/04 01:13:37 UTC

[2/3] git commit: Move *PropDefs to o.a.c.cql3.statements

Move *PropDefs to o.a.c.cql3.statements


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/be9a70eb
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/be9a70eb
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/be9a70eb

Branch: refs/heads/trunk
Commit: be9a70eb3bd7a454cc5d26fc22858fe90e311e05
Parents: d278b7c
Author: Aleksey Yeschenko <al...@apache.org>
Authored: Sat Jan 4 03:08:20 2014 +0300
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Sat Jan 4 03:08:20 2014 +0300

----------------------------------------------------------------------
 .../org/apache/cassandra/cql3/CFPropDefs.java   | 189 -------------------
 .../org/apache/cassandra/cql3/KSPropDefs.java   |  89 ---------
 .../cassandra/cql3/PropertyDefinitions.java     | 143 --------------
 .../cql3/statements/AlterKeyspaceStatement.java |   1 -
 .../cassandra/cql3/statements/CFPropDefs.java   | 189 +++++++++++++++++++
 .../statements/CreateKeyspaceStatement.java     |   1 -
 .../cassandra/cql3/statements/KSPropDefs.java   |  89 +++++++++
 .../cql3/statements/PropertyDefinitions.java    | 143 ++++++++++++++
 .../SizeTieredCompactionStrategy.java           |   2 +-
 9 files changed, 422 insertions(+), 424 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/CFPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/CFPropDefs.java b/src/java/org/apache/cassandra/cql3/CFPropDefs.java
deleted file mode 100644
index 3838ad2..0000000
--- a/src/java/org/apache/cassandra/cql3/CFPropDefs.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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.cql3;
-
-import java.util.*;
-
-import org.apache.cassandra.config.CFMetaData;
-import org.apache.cassandra.config.CFMetaData.SpeculativeRetry;
-import org.apache.cassandra.db.compaction.AbstractCompactionStrategy;
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.exceptions.SyntaxException;
-import org.apache.cassandra.io.compress.CompressionParameters;
-
-public class CFPropDefs extends PropertyDefinitions
-{
-    public static final String KW_COMMENT = "comment";
-    public static final String KW_READREPAIRCHANCE = "read_repair_chance";
-    public static final String KW_DCLOCALREADREPAIRCHANCE = "dclocal_read_repair_chance";
-    public static final String KW_GCGRACESECONDS = "gc_grace_seconds";
-    public static final String KW_MINCOMPACTIONTHRESHOLD = "min_threshold";
-    public static final String KW_MAXCOMPACTIONTHRESHOLD = "max_threshold";
-    public static final String KW_REPLICATEONWRITE = "replicate_on_write";
-    public static final String KW_CACHING = "caching";
-    public static final String KW_DEFAULT_TIME_TO_LIVE = "default_time_to_live";
-    public static final String KW_INDEX_INTERVAL = "index_interval";
-    public static final String KW_SPECULATIVE_RETRY = "speculative_retry";
-    public static final String KW_POPULATE_IO_CACHE_ON_FLUSH = "populate_io_cache_on_flush";
-    public static final String KW_BF_FP_CHANCE = "bloom_filter_fp_chance";
-    public static final String KW_MEMTABLE_FLUSH_PERIOD = "memtable_flush_period_in_ms";
-
-    public static final String KW_COMPACTION = "compaction";
-    public static final String KW_COMPRESSION = "compression";
-
-    public static final String COMPACTION_STRATEGY_CLASS_KEY = "class";
-
-    public static final Set<String> keywords = new HashSet<>();
-    public static final Set<String> obsoleteKeywords = new HashSet<>();
-
-    static
-    {
-        keywords.add(KW_COMMENT);
-        keywords.add(KW_READREPAIRCHANCE);
-        keywords.add(KW_DCLOCALREADREPAIRCHANCE);
-        keywords.add(KW_GCGRACESECONDS);
-        keywords.add(KW_REPLICATEONWRITE);
-        keywords.add(KW_CACHING);
-        keywords.add(KW_DEFAULT_TIME_TO_LIVE);
-        keywords.add(KW_INDEX_INTERVAL);
-        keywords.add(KW_SPECULATIVE_RETRY);
-        keywords.add(KW_POPULATE_IO_CACHE_ON_FLUSH);
-        keywords.add(KW_BF_FP_CHANCE);
-        keywords.add(KW_COMPACTION);
-        keywords.add(KW_COMPRESSION);
-        keywords.add(KW_MEMTABLE_FLUSH_PERIOD);
-    }
-
-    private Class<? extends AbstractCompactionStrategy> compactionStrategyClass = null;
-
-    public void validate() throws ConfigurationException, SyntaxException
-    {
-        // Skip validation if the comapction strategy class is already set as it means we've alreayd
-        // prepared (and redoing it would set strategyClass back to null, which we don't want)
-        if (compactionStrategyClass != null)
-            return;
-
-        validate(keywords, obsoleteKeywords);
-
-        Map<String, String> compactionOptions = getCompactionOptions();
-        if (!compactionOptions.isEmpty())
-        {
-            String strategy = compactionOptions.get(COMPACTION_STRATEGY_CLASS_KEY);
-            if (strategy == null)
-                throw new ConfigurationException("Missing sub-option '" + COMPACTION_STRATEGY_CLASS_KEY + "' for the '" + KW_COMPACTION + "' option.");
-
-            compactionStrategyClass = CFMetaData.createCompactionStrategy(strategy);
-            compactionOptions.remove(COMPACTION_STRATEGY_CLASS_KEY);
-
-            CFMetaData.validateCompactionOptions(compactionStrategyClass, compactionOptions);
-        }
-
-        Map<String, String> compressionOptions = getCompressionOptions();
-        if (!compressionOptions.isEmpty())
-        {
-            String sstableCompressionClass = compressionOptions.get(CompressionParameters.SSTABLE_COMPRESSION);
-            if (sstableCompressionClass == null)
-                throw new ConfigurationException("Missing sub-option '" + CompressionParameters.SSTABLE_COMPRESSION + "' for the '" + KW_COMPRESSION + "' option.");
-
-            Integer chunkLength = CompressionParameters.DEFAULT_CHUNK_LENGTH;
-            if (compressionOptions.containsKey(CompressionParameters.CHUNK_LENGTH_KB))
-                chunkLength = CompressionParameters.parseChunkLength(compressionOptions.get(CompressionParameters.CHUNK_LENGTH_KB));
-
-            Map<String, String> remainingOptions = new HashMap<>(compressionOptions);
-            remainingOptions.remove(CompressionParameters.SSTABLE_COMPRESSION);
-            remainingOptions.remove(CompressionParameters.CHUNK_LENGTH_KB);
-            CompressionParameters cp = new CompressionParameters(sstableCompressionClass, chunkLength, remainingOptions);
-            cp.validate();
-        }
-
-        validateMinimumInt(KW_DEFAULT_TIME_TO_LIVE, 0, CFMetaData.DEFAULT_DEFAULT_TIME_TO_LIVE);
-        validateMinimumInt(KW_INDEX_INTERVAL, 1, CFMetaData.DEFAULT_INDEX_INTERVAL);
-
-        SpeculativeRetry.fromString(getString(KW_SPECULATIVE_RETRY, SpeculativeRetry.RetryType.NONE.name()));
-    }
-
-    public Class<? extends AbstractCompactionStrategy> getCompactionStrategy()
-    {
-        return compactionStrategyClass;
-    }
-
-    public Map<String, String> getCompactionOptions() throws SyntaxException
-    {
-        Map<String, String> compactionOptions = getMap(KW_COMPACTION);
-        if (compactionOptions == null)
-            return new HashMap<>();
-        return compactionOptions;
-    }
-
-    public Map<String, String> getCompressionOptions() throws SyntaxException
-    {
-        Map<String, String> compressionOptions = getMap(KW_COMPRESSION);
-        if (compressionOptions == null)
-            return new HashMap<>();
-        return compressionOptions;
-    }
-
-    public void applyToCFMetadata(CFMetaData cfm) throws ConfigurationException, SyntaxException
-    {
-        if (hasProperty(KW_COMMENT))
-            cfm.comment(getString(KW_COMMENT, ""));
-
-        cfm.readRepairChance(getDouble(KW_READREPAIRCHANCE, cfm.getReadRepairChance()));
-        cfm.dcLocalReadRepairChance(getDouble(KW_DCLOCALREADREPAIRCHANCE, cfm.getDcLocalReadRepair()));
-        cfm.gcGraceSeconds(getInt(KW_GCGRACESECONDS, cfm.getGcGraceSeconds()));
-        cfm.replicateOnWrite(getBoolean(KW_REPLICATEONWRITE, cfm.getReplicateOnWrite()));
-        int minCompactionThreshold = toInt(KW_MINCOMPACTIONTHRESHOLD, getCompactionOptions().get(KW_MINCOMPACTIONTHRESHOLD), cfm.getMinCompactionThreshold());
-        int maxCompactionThreshold = toInt(KW_MAXCOMPACTIONTHRESHOLD, getCompactionOptions().get(KW_MAXCOMPACTIONTHRESHOLD), cfm.getMaxCompactionThreshold());
-        if (minCompactionThreshold <= 0 || maxCompactionThreshold <= 0)
-            throw new ConfigurationException("Disabling compaction by setting compaction thresholds to 0 has been deprecated, set the compaction option 'enabled' to false instead.");
-        cfm.minCompactionThreshold(minCompactionThreshold);
-        cfm.maxCompactionThreshold(maxCompactionThreshold);
-        cfm.caching(CFMetaData.Caching.fromString(getString(KW_CACHING, cfm.getCaching().toString())));
-        cfm.defaultTimeToLive(getInt(KW_DEFAULT_TIME_TO_LIVE, cfm.getDefaultTimeToLive()));
-        cfm.speculativeRetry(CFMetaData.SpeculativeRetry.fromString(getString(KW_SPECULATIVE_RETRY, cfm.getSpeculativeRetry().toString())));
-        cfm.memtableFlushPeriod(getInt(KW_MEMTABLE_FLUSH_PERIOD, cfm.getMemtableFlushPeriod()));
-        cfm.populateIoCacheOnFlush(getBoolean(KW_POPULATE_IO_CACHE_ON_FLUSH, cfm.populateIoCacheOnFlush()));
-        cfm.indexInterval(getInt(KW_INDEX_INTERVAL, cfm.getIndexInterval()));
-
-        if (compactionStrategyClass != null)
-        {
-            cfm.compactionStrategyClass(compactionStrategyClass);
-            cfm.compactionStrategyOptions(new HashMap<>(getCompactionOptions()));
-        }
-
-        cfm.bloomFilterFpChance(getDouble(KW_BF_FP_CHANCE, cfm.getBloomFilterFpChance()));
-
-        if (!getCompressionOptions().isEmpty())
-            cfm.compressionParameters(CompressionParameters.create(getCompressionOptions()));
-    }
-
-    @Override
-    public String toString()
-    {
-        return String.format("CFPropDefs(%s)", properties.toString());
-    }
-
-    private void validateMinimumInt(String field, int minimumValue, int defaultValue) throws SyntaxException, ConfigurationException
-    {
-        Integer val = getInt(field, null);
-        if (val != null && val < minimumValue)
-            throw new ConfigurationException(String.format("%s cannot be smaller than %s, (default %s)",
-                                                            field, minimumValue, defaultValue));
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/KSPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/KSPropDefs.java b/src/java/org/apache/cassandra/cql3/KSPropDefs.java
deleted file mode 100644
index 12fbc51..0000000
--- a/src/java/org/apache/cassandra/cql3/KSPropDefs.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.cql3;
-
-import java.util.*;
-
-import org.apache.cassandra.config.KSMetaData;
-import org.apache.cassandra.exceptions.*;
-
-public class KSPropDefs extends PropertyDefinitions
-{
-    public static final String KW_DURABLE_WRITES = "durable_writes";
-    public static final String KW_REPLICATION = "replication";
-
-    public static final String REPLICATION_STRATEGY_CLASS_KEY = "class";
-
-    public static final Set<String> keywords = new HashSet<>();
-    public static final Set<String> obsoleteKeywords = new HashSet<>();
-
-    static
-    {
-        keywords.add(KW_DURABLE_WRITES);
-        keywords.add(KW_REPLICATION);
-    }
-
-    private String strategyClass;
-
-    public void validate() throws SyntaxException
-    {
-        // Skip validation if the strategy class is already set as it means we've alreayd
-        // prepared (and redoing it would set strategyClass back to null, which we don't want)
-        if (strategyClass != null)
-            return;
-
-        validate(keywords, obsoleteKeywords);
-
-        Map<String, String> replicationOptions = getReplicationOptions();
-        if (!replicationOptions.isEmpty())
-        {
-            strategyClass = replicationOptions.get(REPLICATION_STRATEGY_CLASS_KEY);
-            replicationOptions.remove(REPLICATION_STRATEGY_CLASS_KEY);
-        }
-    }
-
-    public Map<String, String> getReplicationOptions() throws SyntaxException
-    {
-        Map<String, String> replicationOptions = getMap(KW_REPLICATION);
-        if (replicationOptions == null)
-            return Collections.emptyMap();
-        return replicationOptions;
-    }
-
-    public String getReplicationStrategyClass()
-    {
-        return strategyClass;
-    }
-
-    public KSMetaData asKSMetadata(String ksName) throws RequestValidationException
-    {
-        return KSMetaData.newKeyspace(ksName, getReplicationStrategyClass(), getReplicationOptions(), getBoolean(KW_DURABLE_WRITES, true));
-    }
-
-    public KSMetaData asKSMetadataUpdate(KSMetaData old) throws RequestValidationException
-    {
-        String sClass = strategyClass;
-        Map<String, String> sOptions = getReplicationOptions();
-        if (sClass == null)
-        {
-            sClass = old.strategyClass.getName();
-            sOptions = old.strategyOptions;
-        }
-        return KSMetaData.newKeyspace(old.name, sClass, sOptions, getBoolean(KW_DURABLE_WRITES, old.durableWrites));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java b/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
deleted file mode 100644
index b48d27a..0000000
--- a/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.cql3;
-
-import java.util.*;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.cassandra.exceptions.SyntaxException;
-
-public class PropertyDefinitions
-{
-    protected static final Logger logger = LoggerFactory.getLogger(PropertyDefinitions.class);
-
-    protected final Map<String, Object> properties = new HashMap<String, Object>();
-
-    public void addProperty(String name, String value) throws SyntaxException
-    {
-        if (properties.put(name, value) != null)
-            throw new SyntaxException(String.format("Multiple definition for property '%s'", name));
-    }
-
-    public void addProperty(String name, Map<String, String> value) throws SyntaxException
-    {
-        if (properties.put(name, value) != null)
-            throw new SyntaxException(String.format("Multiple definition for property '%s'", name));
-    }
-
-    public void validate(Set<String> keywords, Set<String> obsolete) throws SyntaxException
-    {
-        for (String name : properties.keySet())
-        {
-            if (keywords.contains(name))
-                continue;
-
-            if (obsolete.contains(name))
-                logger.warn("Ignoring obsolete property {}", name);
-            else
-                throw new SyntaxException(String.format("Unknown property '%s'", name));
-        }
-    }
-
-    protected String getSimple(String name) throws SyntaxException
-    {
-        Object val = properties.get(name);
-        if (val == null)
-            return null;
-        if (!(val instanceof String))
-            throw new SyntaxException(String.format("Invalid value for property '%s'. It should be a string", name));
-        return (String)val;
-    }
-
-    protected Map<String, String> getMap(String name) throws SyntaxException
-    {
-        Object val = properties.get(name);
-        if (val == null)
-            return null;
-        if (!(val instanceof Map))
-            throw new SyntaxException(String.format("Invalid value for property '%s'. It should be a map.", name));
-        return (Map<String, String>)val;
-    }
-
-    public Boolean hasProperty(String name)
-    {
-        return properties.containsKey(name);
-    }
-
-    public String getString(String key, String defaultValue) throws SyntaxException
-    {
-        String value = getSimple(key);
-        return value != null ? value : defaultValue;
-    }
-
-    // Return a property value, typed as a Boolean
-    public Boolean getBoolean(String key, Boolean defaultValue) throws SyntaxException
-    {
-        String value = getSimple(key);
-        return (value == null) ? defaultValue : value.toLowerCase().matches("(1|true|yes)");
-    }
-
-    // Return a property value, typed as a Double
-    public Double getDouble(String key, Double defaultValue) throws SyntaxException
-    {
-        String value = getSimple(key);
-        if (value == null)
-        {
-            return defaultValue;
-        }
-        else
-        {
-            try
-            {
-                return Double.valueOf(value);
-            }
-            catch (NumberFormatException e)
-            {
-                throw new SyntaxException(String.format("Invalid double value %s for '%s'", value, key));
-            }
-        }
-    }
-
-    // Return a property value, typed as an Integer
-    public Integer getInt(String key, Integer defaultValue) throws SyntaxException
-    {
-        String value = getSimple(key);
-        return toInt(key, value, defaultValue);
-    }
-
-    public static Integer toInt(String key, String value, Integer defaultValue) throws SyntaxException
-    {
-        if (value == null)
-        {
-            return defaultValue;
-        }
-        else
-        {
-            try
-            {
-                return Integer.valueOf(value);
-            }
-            catch (NumberFormatException e)
-            {
-                throw new SyntaxException(String.format("Invalid integer value %s for '%s'", value, key));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
index d05fe26..39d1cde 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
@@ -21,7 +21,6 @@ import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.KSMetaData;
 import org.apache.cassandra.config.Schema;
-import org.apache.cassandra.cql3.KSPropDefs;
 import org.apache.cassandra.db.Keyspace;
 import org.apache.cassandra.exceptions.*;
 import org.apache.cassandra.locator.AbstractReplicationStrategy;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/statements/CFPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CFPropDefs.java b/src/java/org/apache/cassandra/cql3/statements/CFPropDefs.java
new file mode 100644
index 0000000..6ce6406
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/statements/CFPropDefs.java
@@ -0,0 +1,189 @@
+/*
+ * 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.cql3.statements;
+
+import java.util.*;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.CFMetaData.SpeculativeRetry;
+import org.apache.cassandra.db.compaction.AbstractCompactionStrategy;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.exceptions.SyntaxException;
+import org.apache.cassandra.io.compress.CompressionParameters;
+
+public class CFPropDefs extends PropertyDefinitions
+{
+    public static final String KW_COMMENT = "comment";
+    public static final String KW_READREPAIRCHANCE = "read_repair_chance";
+    public static final String KW_DCLOCALREADREPAIRCHANCE = "dclocal_read_repair_chance";
+    public static final String KW_GCGRACESECONDS = "gc_grace_seconds";
+    public static final String KW_MINCOMPACTIONTHRESHOLD = "min_threshold";
+    public static final String KW_MAXCOMPACTIONTHRESHOLD = "max_threshold";
+    public static final String KW_REPLICATEONWRITE = "replicate_on_write";
+    public static final String KW_CACHING = "caching";
+    public static final String KW_DEFAULT_TIME_TO_LIVE = "default_time_to_live";
+    public static final String KW_INDEX_INTERVAL = "index_interval";
+    public static final String KW_SPECULATIVE_RETRY = "speculative_retry";
+    public static final String KW_POPULATE_IO_CACHE_ON_FLUSH = "populate_io_cache_on_flush";
+    public static final String KW_BF_FP_CHANCE = "bloom_filter_fp_chance";
+    public static final String KW_MEMTABLE_FLUSH_PERIOD = "memtable_flush_period_in_ms";
+
+    public static final String KW_COMPACTION = "compaction";
+    public static final String KW_COMPRESSION = "compression";
+
+    public static final String COMPACTION_STRATEGY_CLASS_KEY = "class";
+
+    public static final Set<String> keywords = new HashSet<>();
+    public static final Set<String> obsoleteKeywords = new HashSet<>();
+
+    static
+    {
+        keywords.add(KW_COMMENT);
+        keywords.add(KW_READREPAIRCHANCE);
+        keywords.add(KW_DCLOCALREADREPAIRCHANCE);
+        keywords.add(KW_GCGRACESECONDS);
+        keywords.add(KW_REPLICATEONWRITE);
+        keywords.add(KW_CACHING);
+        keywords.add(KW_DEFAULT_TIME_TO_LIVE);
+        keywords.add(KW_INDEX_INTERVAL);
+        keywords.add(KW_SPECULATIVE_RETRY);
+        keywords.add(KW_POPULATE_IO_CACHE_ON_FLUSH);
+        keywords.add(KW_BF_FP_CHANCE);
+        keywords.add(KW_COMPACTION);
+        keywords.add(KW_COMPRESSION);
+        keywords.add(KW_MEMTABLE_FLUSH_PERIOD);
+    }
+
+    private Class<? extends AbstractCompactionStrategy> compactionStrategyClass = null;
+
+    public void validate() throws ConfigurationException, SyntaxException
+    {
+        // Skip validation if the comapction strategy class is already set as it means we've alreayd
+        // prepared (and redoing it would set strategyClass back to null, which we don't want)
+        if (compactionStrategyClass != null)
+            return;
+
+        validate(keywords, obsoleteKeywords);
+
+        Map<String, String> compactionOptions = getCompactionOptions();
+        if (!compactionOptions.isEmpty())
+        {
+            String strategy = compactionOptions.get(COMPACTION_STRATEGY_CLASS_KEY);
+            if (strategy == null)
+                throw new ConfigurationException("Missing sub-option '" + COMPACTION_STRATEGY_CLASS_KEY + "' for the '" + KW_COMPACTION + "' option.");
+
+            compactionStrategyClass = CFMetaData.createCompactionStrategy(strategy);
+            compactionOptions.remove(COMPACTION_STRATEGY_CLASS_KEY);
+
+            CFMetaData.validateCompactionOptions(compactionStrategyClass, compactionOptions);
+        }
+
+        Map<String, String> compressionOptions = getCompressionOptions();
+        if (!compressionOptions.isEmpty())
+        {
+            String sstableCompressionClass = compressionOptions.get(CompressionParameters.SSTABLE_COMPRESSION);
+            if (sstableCompressionClass == null)
+                throw new ConfigurationException("Missing sub-option '" + CompressionParameters.SSTABLE_COMPRESSION + "' for the '" + KW_COMPRESSION + "' option.");
+
+            Integer chunkLength = CompressionParameters.DEFAULT_CHUNK_LENGTH;
+            if (compressionOptions.containsKey(CompressionParameters.CHUNK_LENGTH_KB))
+                chunkLength = CompressionParameters.parseChunkLength(compressionOptions.get(CompressionParameters.CHUNK_LENGTH_KB));
+
+            Map<String, String> remainingOptions = new HashMap<>(compressionOptions);
+            remainingOptions.remove(CompressionParameters.SSTABLE_COMPRESSION);
+            remainingOptions.remove(CompressionParameters.CHUNK_LENGTH_KB);
+            CompressionParameters cp = new CompressionParameters(sstableCompressionClass, chunkLength, remainingOptions);
+            cp.validate();
+        }
+
+        validateMinimumInt(KW_DEFAULT_TIME_TO_LIVE, 0, CFMetaData.DEFAULT_DEFAULT_TIME_TO_LIVE);
+        validateMinimumInt(KW_INDEX_INTERVAL, 1, CFMetaData.DEFAULT_INDEX_INTERVAL);
+
+        SpeculativeRetry.fromString(getString(KW_SPECULATIVE_RETRY, SpeculativeRetry.RetryType.NONE.name()));
+    }
+
+    public Class<? extends AbstractCompactionStrategy> getCompactionStrategy()
+    {
+        return compactionStrategyClass;
+    }
+
+    public Map<String, String> getCompactionOptions() throws SyntaxException
+    {
+        Map<String, String> compactionOptions = getMap(KW_COMPACTION);
+        if (compactionOptions == null)
+            return new HashMap<>();
+        return compactionOptions;
+    }
+
+    public Map<String, String> getCompressionOptions() throws SyntaxException
+    {
+        Map<String, String> compressionOptions = getMap(KW_COMPRESSION);
+        if (compressionOptions == null)
+            return new HashMap<>();
+        return compressionOptions;
+    }
+
+    public void applyToCFMetadata(CFMetaData cfm) throws ConfigurationException, SyntaxException
+    {
+        if (hasProperty(KW_COMMENT))
+            cfm.comment(getString(KW_COMMENT, ""));
+
+        cfm.readRepairChance(getDouble(KW_READREPAIRCHANCE, cfm.getReadRepairChance()));
+        cfm.dcLocalReadRepairChance(getDouble(KW_DCLOCALREADREPAIRCHANCE, cfm.getDcLocalReadRepair()));
+        cfm.gcGraceSeconds(getInt(KW_GCGRACESECONDS, cfm.getGcGraceSeconds()));
+        cfm.replicateOnWrite(getBoolean(KW_REPLICATEONWRITE, cfm.getReplicateOnWrite()));
+        int minCompactionThreshold = toInt(KW_MINCOMPACTIONTHRESHOLD, getCompactionOptions().get(KW_MINCOMPACTIONTHRESHOLD), cfm.getMinCompactionThreshold());
+        int maxCompactionThreshold = toInt(KW_MAXCOMPACTIONTHRESHOLD, getCompactionOptions().get(KW_MAXCOMPACTIONTHRESHOLD), cfm.getMaxCompactionThreshold());
+        if (minCompactionThreshold <= 0 || maxCompactionThreshold <= 0)
+            throw new ConfigurationException("Disabling compaction by setting compaction thresholds to 0 has been deprecated, set the compaction option 'enabled' to false instead.");
+        cfm.minCompactionThreshold(minCompactionThreshold);
+        cfm.maxCompactionThreshold(maxCompactionThreshold);
+        cfm.caching(CFMetaData.Caching.fromString(getString(KW_CACHING, cfm.getCaching().toString())));
+        cfm.defaultTimeToLive(getInt(KW_DEFAULT_TIME_TO_LIVE, cfm.getDefaultTimeToLive()));
+        cfm.speculativeRetry(CFMetaData.SpeculativeRetry.fromString(getString(KW_SPECULATIVE_RETRY, cfm.getSpeculativeRetry().toString())));
+        cfm.memtableFlushPeriod(getInt(KW_MEMTABLE_FLUSH_PERIOD, cfm.getMemtableFlushPeriod()));
+        cfm.populateIoCacheOnFlush(getBoolean(KW_POPULATE_IO_CACHE_ON_FLUSH, cfm.populateIoCacheOnFlush()));
+        cfm.indexInterval(getInt(KW_INDEX_INTERVAL, cfm.getIndexInterval()));
+
+        if (compactionStrategyClass != null)
+        {
+            cfm.compactionStrategyClass(compactionStrategyClass);
+            cfm.compactionStrategyOptions(new HashMap<>(getCompactionOptions()));
+        }
+
+        cfm.bloomFilterFpChance(getDouble(KW_BF_FP_CHANCE, cfm.getBloomFilterFpChance()));
+
+        if (!getCompressionOptions().isEmpty())
+            cfm.compressionParameters(CompressionParameters.create(getCompressionOptions()));
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("CFPropDefs(%s)", properties.toString());
+    }
+
+    private void validateMinimumInt(String field, int minimumValue, int defaultValue) throws SyntaxException, ConfigurationException
+    {
+        Integer val = getInt(field, null);
+        if (val != null && val < minimumValue)
+            throw new ConfigurationException(String.format("%s cannot be smaller than %s, (default %s)",
+                                                            field, minimumValue, defaultValue));
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
index 8245453..2ed1d91 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -21,7 +21,6 @@ import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.Schema;
-import org.apache.cassandra.cql3.KSPropDefs;
 import org.apache.cassandra.exceptions.AlreadyExistsException;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/statements/KSPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/KSPropDefs.java b/src/java/org/apache/cassandra/cql3/statements/KSPropDefs.java
new file mode 100644
index 0000000..7c05435
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/statements/KSPropDefs.java
@@ -0,0 +1,89 @@
+/*
+ * 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.cql3.statements;
+
+import java.util.*;
+
+import org.apache.cassandra.config.KSMetaData;
+import org.apache.cassandra.exceptions.*;
+
+public class KSPropDefs extends PropertyDefinitions
+{
+    public static final String KW_DURABLE_WRITES = "durable_writes";
+    public static final String KW_REPLICATION = "replication";
+
+    public static final String REPLICATION_STRATEGY_CLASS_KEY = "class";
+
+    public static final Set<String> keywords = new HashSet<>();
+    public static final Set<String> obsoleteKeywords = new HashSet<>();
+
+    static
+    {
+        keywords.add(KW_DURABLE_WRITES);
+        keywords.add(KW_REPLICATION);
+    }
+
+    private String strategyClass;
+
+    public void validate() throws SyntaxException
+    {
+        // Skip validation if the strategy class is already set as it means we've alreayd
+        // prepared (and redoing it would set strategyClass back to null, which we don't want)
+        if (strategyClass != null)
+            return;
+
+        validate(keywords, obsoleteKeywords);
+
+        Map<String, String> replicationOptions = getReplicationOptions();
+        if (!replicationOptions.isEmpty())
+        {
+            strategyClass = replicationOptions.get(REPLICATION_STRATEGY_CLASS_KEY);
+            replicationOptions.remove(REPLICATION_STRATEGY_CLASS_KEY);
+        }
+    }
+
+    public Map<String, String> getReplicationOptions() throws SyntaxException
+    {
+        Map<String, String> replicationOptions = getMap(KW_REPLICATION);
+        if (replicationOptions == null)
+            return Collections.emptyMap();
+        return replicationOptions;
+    }
+
+    public String getReplicationStrategyClass()
+    {
+        return strategyClass;
+    }
+
+    public KSMetaData asKSMetadata(String ksName) throws RequestValidationException
+    {
+        return KSMetaData.newKeyspace(ksName, getReplicationStrategyClass(), getReplicationOptions(), getBoolean(KW_DURABLE_WRITES, true));
+    }
+
+    public KSMetaData asKSMetadataUpdate(KSMetaData old) throws RequestValidationException
+    {
+        String sClass = strategyClass;
+        Map<String, String> sOptions = getReplicationOptions();
+        if (sClass == null)
+        {
+            sClass = old.strategyClass.getName();
+            sOptions = old.strategyOptions;
+        }
+        return KSMetaData.newKeyspace(old.name, sClass, sOptions, getBoolean(KW_DURABLE_WRITES, old.durableWrites));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
new file mode 100644
index 0000000..eb4f074
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/statements/PropertyDefinitions.java
@@ -0,0 +1,143 @@
+/*
+ * 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.cql3.statements;
+
+import java.util.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.exceptions.SyntaxException;
+
+public class PropertyDefinitions
+{
+    protected static final Logger logger = LoggerFactory.getLogger(PropertyDefinitions.class);
+
+    protected final Map<String, Object> properties = new HashMap<String, Object>();
+
+    public void addProperty(String name, String value) throws SyntaxException
+    {
+        if (properties.put(name, value) != null)
+            throw new SyntaxException(String.format("Multiple definition for property '%s'", name));
+    }
+
+    public void addProperty(String name, Map<String, String> value) throws SyntaxException
+    {
+        if (properties.put(name, value) != null)
+            throw new SyntaxException(String.format("Multiple definition for property '%s'", name));
+    }
+
+    public void validate(Set<String> keywords, Set<String> obsolete) throws SyntaxException
+    {
+        for (String name : properties.keySet())
+        {
+            if (keywords.contains(name))
+                continue;
+
+            if (obsolete.contains(name))
+                logger.warn("Ignoring obsolete property {}", name);
+            else
+                throw new SyntaxException(String.format("Unknown property '%s'", name));
+        }
+    }
+
+    protected String getSimple(String name) throws SyntaxException
+    {
+        Object val = properties.get(name);
+        if (val == null)
+            return null;
+        if (!(val instanceof String))
+            throw new SyntaxException(String.format("Invalid value for property '%s'. It should be a string", name));
+        return (String)val;
+    }
+
+    protected Map<String, String> getMap(String name) throws SyntaxException
+    {
+        Object val = properties.get(name);
+        if (val == null)
+            return null;
+        if (!(val instanceof Map))
+            throw new SyntaxException(String.format("Invalid value for property '%s'. It should be a map.", name));
+        return (Map<String, String>)val;
+    }
+
+    public Boolean hasProperty(String name)
+    {
+        return properties.containsKey(name);
+    }
+
+    public String getString(String key, String defaultValue) throws SyntaxException
+    {
+        String value = getSimple(key);
+        return value != null ? value : defaultValue;
+    }
+
+    // Return a property value, typed as a Boolean
+    public Boolean getBoolean(String key, Boolean defaultValue) throws SyntaxException
+    {
+        String value = getSimple(key);
+        return (value == null) ? defaultValue : value.toLowerCase().matches("(1|true|yes)");
+    }
+
+    // Return a property value, typed as a Double
+    public Double getDouble(String key, Double defaultValue) throws SyntaxException
+    {
+        String value = getSimple(key);
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        else
+        {
+            try
+            {
+                return Double.valueOf(value);
+            }
+            catch (NumberFormatException e)
+            {
+                throw new SyntaxException(String.format("Invalid double value %s for '%s'", value, key));
+            }
+        }
+    }
+
+    // Return a property value, typed as an Integer
+    public Integer getInt(String key, Integer defaultValue) throws SyntaxException
+    {
+        String value = getSimple(key);
+        return toInt(key, value, defaultValue);
+    }
+
+    public static Integer toInt(String key, String value, Integer defaultValue) throws SyntaxException
+    {
+        if (value == null)
+        {
+            return defaultValue;
+        }
+        else
+        {
+            try
+            {
+                return Integer.valueOf(value);
+            }
+            catch (NumberFormatException e)
+            {
+                throw new SyntaxException(String.format("Invalid integer value %s for '%s'", value, key));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/be9a70eb/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java
index 51464ab..0f94918 100644
--- a/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java
+++ b/src/java/org/apache/cassandra/db/compaction/SizeTieredCompactionStrategy.java
@@ -26,7 +26,7 @@ import com.google.common.collect.Lists;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.cassandra.cql3.CFPropDefs;
+import org.apache.cassandra.cql3.statements.CFPropDefs;
 import org.apache.cassandra.db.ColumnFamilyStore;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.io.sstable.SSTableReader;