mirror of https://github.com/apache/cassandra
tool to import+export schema. patch by Eric Evans and Gary Dusbabek, reviewed by Brandon Williams. CASSANDRA-1133
git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@967261 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e3f05adf36
commit
a677749228
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
|
||||
if [ "x$CASSANDRA_INCLUDE" = "x" ]; then
|
||||
for include in /usr/share/cassandra/cassandra.in.sh \
|
||||
/usr/local/share/cassandra/cassandra.in.sh \
|
||||
/opt/cassandra/cassandra.in.sh \
|
||||
~/.cassandra.in.sh \
|
||||
`dirname $0`/cassandra.in.sh; do
|
||||
if [ -r $include ]; then
|
||||
. $include
|
||||
break
|
||||
fi
|
||||
done
|
||||
elif [ -r $CASSANDRA_INCLUDE ]; then
|
||||
. $CASSANDRA_INCLUDE
|
||||
fi
|
||||
|
||||
# Use JAVA_HOME if set, otherwise look for java in PATH
|
||||
if [ -x $JAVA_HOME/bin/java ]; then
|
||||
JAVA=$JAVA_HOME/bin/java
|
||||
else
|
||||
JAVA=`which java`
|
||||
fi
|
||||
|
||||
if [ -z $CLASSPATH ]; then
|
||||
echo "You must set the CLASSPATH var" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$JAVA -cp $CLASSPATH -Dlog4j.configuration=log4j-tools.properties \
|
||||
org.apache.cassandra.tools.SchemaTool "$@"
|
||||
|
||||
# vi:ai sw=4 ts=4 tw=0 et
|
||||
|
|
@ -12,6 +12,7 @@ import javax.xml.transform.TransformerException;
|
|||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
import org.apache.cassandra.utils.SkipNullRepresenter;
|
||||
import org.apache.cassandra.utils.XMLUtils;
|
||||
import org.apache.cassandra.db.ColumnFamilyType;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
|
@ -319,18 +320,4 @@ public class Converter
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/* used to prevent null values from being included in generated YAML */
|
||||
private static class SkipNullRepresenter extends Representer {
|
||||
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
|
||||
Object propertyValue, Tag customTag) {
|
||||
if (propertyValue == null) {
|
||||
return null;
|
||||
} else {
|
||||
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ import java.util.concurrent.*;
|
|||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.apache.cassandra.config.CFMetaData;
|
||||
import org.apache.cassandra.config.ColumnDefinition;
|
||||
import org.apache.cassandra.config.Config;
|
||||
import org.apache.cassandra.config.RawColumnDefinition;
|
||||
import org.apache.cassandra.config.RawColumnFamily;
|
||||
import org.apache.cassandra.config.RawKeyspace;
|
||||
import org.apache.cassandra.utils.SkipNullRepresenter;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
|
@ -67,6 +74,13 @@ import org.apache.cassandra.thrift.UnavailableException;
|
|||
import org.apache.cassandra.utils.FBUtilities;
|
||||
import org.apache.cassandra.utils.WrappedRunnable;
|
||||
import org.apache.log4j.Level;
|
||||
import org.yaml.snakeyaml.Dumper;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.introspector.Property;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
/*
|
||||
* This abstraction contains the token/identifier of this node
|
||||
|
|
@ -1677,6 +1691,71 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe
|
|||
|
||||
}
|
||||
|
||||
public String exportSchema() throws IOException
|
||||
{
|
||||
List<RawKeyspace> keyspaces = new ArrayList<RawKeyspace>();
|
||||
for (String ksname : DatabaseDescriptor.getNonSystemTables())
|
||||
{
|
||||
KSMetaData ksm = DatabaseDescriptor.getTableDefinition(ksname);
|
||||
RawKeyspace rks = new RawKeyspace();
|
||||
rks.name = ksm.name;
|
||||
rks.replica_placement_strategy = ksm.strategyClass.getName();
|
||||
rks.replication_factor = ksm.replicationFactor;
|
||||
rks.column_families = new RawColumnFamily[ksm.cfMetaData().size()];
|
||||
int i = 0;
|
||||
for (CFMetaData cfm : ksm.cfMetaData().values())
|
||||
{
|
||||
RawColumnFamily rcf = new RawColumnFamily();
|
||||
rcf.name = cfm.cfName;
|
||||
rcf.compare_with = cfm.comparator.getClass().getName();
|
||||
rcf.compare_subcolumns_with = cfm.subcolumnComparator == null ? null : cfm.subcolumnComparator.getClass().getName();
|
||||
rcf.clock_type = cfm.clockType;
|
||||
rcf.column_type = cfm.cfType;
|
||||
rcf.comment = cfm.comment;
|
||||
rcf.keys_cached = cfm.keyCacheSize;
|
||||
rcf.preload_row_cache = cfm.preloadRowCache;
|
||||
rcf.read_repair_chance = cfm.readRepairChance;
|
||||
rcf.reconciler = cfm.reconciler.getClass().getName();
|
||||
rcf.rows_cached = cfm.rowCacheSize;
|
||||
rcf.column_metadata = new RawColumnDefinition[cfm.column_metadata.size()];
|
||||
int j = 0;
|
||||
for (ColumnDefinition cd : cfm.column_metadata.values())
|
||||
{
|
||||
RawColumnDefinition rcd = new RawColumnDefinition();
|
||||
rcd.index_name = cd.index_name;
|
||||
rcd.index_type = cd.index_type;
|
||||
rcd.name = new String(cd.name, "UTF8");
|
||||
rcd.validator_class = cd.validator.getClass().getName();
|
||||
rcf.column_metadata[j++] = rcd;
|
||||
}
|
||||
if (j == 0)
|
||||
rcf.column_metadata = null;
|
||||
rks.column_families[i++] = rcf;
|
||||
}
|
||||
// whew.
|
||||
keyspaces.add(rks);
|
||||
}
|
||||
|
||||
DumperOptions options = new DumperOptions();
|
||||
/* Use a block YAML arrangement */
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
SkipNullRepresenter representer = new SkipNullRepresenter();
|
||||
/* Use Tag.MAP to avoid the class name being included as global tag */
|
||||
representer.addClassTag(RawColumnFamily.class, Tag.MAP);
|
||||
representer.addClassTag(Keyspaces.class, Tag.MAP);
|
||||
representer.addClassTag(ColumnDefinition.class, Tag.MAP);
|
||||
Dumper dumper = new Dumper(representer, options);
|
||||
Yaml yaml = new Yaml(dumper);
|
||||
Keyspaces ks = new Keyspaces();
|
||||
ks.keyspaces = keyspaces;
|
||||
return yaml.dump(ks);
|
||||
}
|
||||
|
||||
public class Keyspaces
|
||||
{
|
||||
public List<RawKeyspace> keyspaces;
|
||||
}
|
||||
|
||||
// Never ever do this at home. Used by tests.
|
||||
Map<String, AbstractReplicationStrategy> setReplicationStrategyUnsafe(Map<String, AbstractReplicationStrategy> replacement)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -206,6 +206,12 @@ public interface StorageServiceMBean
|
|||
*/
|
||||
public void loadSchemaFromYAML() throws ConfigurationException, IOException;
|
||||
|
||||
/**
|
||||
* Introduced in 0.7 to allow schema yaml to be exported.
|
||||
* @todo: deprecate in 0.7+1, remove in 0.7+2.
|
||||
*/
|
||||
public String exportSchema() throws IOException;
|
||||
|
||||
/**
|
||||
* Truncates (deletes) the given columnFamily from the provided keyspace.
|
||||
* Calling truncate results in actual deletion of all data in the cluster
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import javax.management.remote.JMXServiceURL;
|
|||
|
||||
import org.apache.cassandra.cache.JMXInstrumentedCacheMBean;
|
||||
import org.apache.cassandra.concurrent.IExecutorMBean;
|
||||
import org.apache.cassandra.config.ConfigurationException;
|
||||
import org.apache.cassandra.db.ColumnFamilyStoreMBean;
|
||||
import org.apache.cassandra.db.CompactionManager;
|
||||
import org.apache.cassandra.db.CompactionManagerMBean;
|
||||
|
|
@ -407,6 +408,17 @@ public class NodeProbe
|
|||
throw new RuntimeException("Error while executing truncate", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void loadSchemaFromYAML() throws ConfigurationException, IOException
|
||||
{
|
||||
ssProxy.loadSchemaFromYAML();
|
||||
}
|
||||
|
||||
public String exportSchemaToYAML() throws IOException
|
||||
{
|
||||
return ssProxy.exportSchema();
|
||||
}
|
||||
}
|
||||
|
||||
class ColumnFamilyStoreMBeanIterator implements Iterator<Map.Entry<String, ColumnFamilyStoreMBean>>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package org.apache.cassandra.tools;
|
||||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import org.apache.cassandra.config.ConfigurationException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SchemaTool
|
||||
{
|
||||
public static void main(String[] args)
|
||||
throws NumberFormatException, IOException, InterruptedException, ConfigurationException
|
||||
{
|
||||
if (args.length != 3)
|
||||
usage();
|
||||
|
||||
System.out.println("# Note: This tool is deprecated and will be removed in future releases.");
|
||||
|
||||
String host = args[0];
|
||||
int port = 0;
|
||||
|
||||
try
|
||||
{
|
||||
port = Integer.parseInt(args[1]);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.err.println("Port must be a number.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if ("import".equals(args[2]))
|
||||
new NodeProbe(host, port).loadSchemaFromYAML();
|
||||
else if ("export".equals(args[2]))
|
||||
System.out.println(new NodeProbe(host, port).exportSchemaToYAML());
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
||||
private static void usage()
|
||||
{
|
||||
System.err.printf("java %s <host> <port> import|export%n", SchemaTool.class.getName());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package org.apache.cassandra.utils;
|
||||
|
||||
import org.yaml.snakeyaml.introspector.Property;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/* used to prevent null values from being included in generated YAML */
|
||||
public class SkipNullRepresenter extends Representer
|
||||
{
|
||||
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag)
|
||||
{
|
||||
if (propertyValue == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue