From a5aefb5ef26e28a76b900ced5ad928699f18ced4 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 9 Mar 2015 11:53:26 +0200 Subject: [PATCH] config: Import KSMetaData.java Signed-off-by: Pekka Enberg --- config/KSMetaData.java | 184 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 config/KSMetaData.java diff --git a/config/KSMetaData.java b/config/KSMetaData.java new file mode 100644 index 0000000000..1537aae803 --- /dev/null +++ b/config/KSMetaData.java @@ -0,0 +1,184 @@ +/* + * 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.config; + +import java.util.*; + +import com.google.common.base.Objects; + +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.locator.*; +import org.apache.cassandra.service.StorageService; + +public final class KSMetaData +{ + public final String name; + public final Class strategyClass; + public final Map strategyOptions; + private final Map cfMetaData; + public final boolean durableWrites; + + public final UTMetaData userTypes; + + public KSMetaData(String name, + Class strategyClass, + Map strategyOptions, + boolean durableWrites) + { + this(name, strategyClass, strategyOptions, durableWrites, Collections.emptyList(), new UTMetaData()); + } + + public KSMetaData(String name, + Class strategyClass, + Map strategyOptions, + boolean durableWrites, + Iterable cfDefs) + { + this(name, strategyClass, strategyOptions, durableWrites, cfDefs, new UTMetaData()); + } + + private KSMetaData(String name, + Class strategyClass, + Map strategyOptions, + boolean durableWrites, + Iterable cfDefs, + UTMetaData userTypes) + { + this.name = name; + this.strategyClass = strategyClass == null ? NetworkTopologyStrategy.class : strategyClass; + this.strategyOptions = strategyOptions; + Map cfmap = new HashMap<>(); + for (CFMetaData cfm : cfDefs) + cfmap.put(cfm.cfName, cfm); + this.cfMetaData = Collections.unmodifiableMap(cfmap); + this.durableWrites = durableWrites; + this.userTypes = userTypes; + } + + // For new user created keyspaces (through CQL) + public static KSMetaData newKeyspace(String name, String strategyName, Map options, boolean durableWrites) throws ConfigurationException + { + Class cls = AbstractReplicationStrategy.getClass(strategyName); + if (cls.equals(LocalStrategy.class)) + throw new ConfigurationException("Unable to use given strategy class: LocalStrategy is reserved for internal use."); + + return newKeyspace(name, cls, options, durableWrites, Collections.emptyList()); + } + + public static KSMetaData newKeyspace(String name, Class strategyClass, Map options, boolean durablesWrites, Iterable cfDefs) + { + return new KSMetaData(name, strategyClass, options, durablesWrites, cfDefs, new UTMetaData()); + } + + public KSMetaData cloneWithTableRemoved(CFMetaData table) + { + // clone ksm but do not include the new table + List newTables = new ArrayList<>(cfMetaData().values()); + newTables.remove(table); + assert newTables.size() == cfMetaData().size() - 1; + return cloneWith(newTables, userTypes); + } + + public KSMetaData cloneWithTableAdded(CFMetaData table) + { + // clone ksm but include the new table + List newTables = new ArrayList<>(cfMetaData().values()); + newTables.add(table); + assert newTables.size() == cfMetaData().size() + 1; + return cloneWith(newTables, userTypes); + } + + public KSMetaData cloneWith(Iterable tables, UTMetaData types) + { + return new KSMetaData(name, strategyClass, strategyOptions, durableWrites, tables, types); + } + + public static KSMetaData testMetadata(String name, Class strategyClass, Map strategyOptions, CFMetaData... cfDefs) + { + return new KSMetaData(name, strategyClass, strategyOptions, true, Arrays.asList(cfDefs)); + } + + public static KSMetaData testMetadataNotDurable(String name, Class strategyClass, Map strategyOptions, CFMetaData... cfDefs) + { + return new KSMetaData(name, strategyClass, strategyOptions, false, Arrays.asList(cfDefs)); + } + + @Override + public int hashCode() + { + return Objects.hashCode(name, strategyClass, strategyOptions, cfMetaData, durableWrites, userTypes); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + + if (!(o instanceof KSMetaData)) + return false; + + KSMetaData other = (KSMetaData) o; + + return Objects.equal(name, other.name) + && Objects.equal(strategyClass, other.strategyClass) + && Objects.equal(strategyOptions, other.strategyOptions) + && Objects.equal(cfMetaData, other.cfMetaData) + && Objects.equal(durableWrites, other.durableWrites) + && Objects.equal(userTypes, other.userTypes); + } + + public Map cfMetaData() + { + return cfMetaData; + } + + @Override + public String toString() + { + return Objects.toStringHelper(this) + .add("name", name) + .add("strategyClass", strategyClass.getSimpleName()) + .add("strategyOptions", strategyOptions) + .add("cfMetaData", cfMetaData) + .add("durableWrites", durableWrites) + .add("userTypes", userTypes) + .toString(); + } + + public static Map optsWithRF(final Integer rf) + { + return Collections.singletonMap("replication_factor", rf.toString()); + } + + public KSMetaData validate() throws ConfigurationException + { + if (!CFMetaData.isNameValid(name)) + throw new ConfigurationException(String.format("Keyspace name must not be empty, more than %s characters long, or contain non-alphanumeric-underscore characters (got \"%s\")", Schema.NAME_LENGTH, name)); + + // Attempt to instantiate the ARS, which will throw a ConfigException if the strategy_options aren't fully formed + TokenMetadata tmd = StorageService.instance.getTokenMetadata(); + IEndpointSnitch eps = DatabaseDescriptor.getEndpointSnitch(); + AbstractReplicationStrategy.validateReplicationStrategy(name, strategyClass, tmd, eps, strategyOptions); + + for (CFMetaData cfm : cfMetaData.values()) + cfm.validate(); + + return this; + } +}