Read Cassandra Key in mapping file
Project: http://git-wip-us.apache.org/repos/asf/gora/repo Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/6617b0bb Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/6617b0bb Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/6617b0bb Branch: refs/heads/master Commit: 6617b0bb81b7c7da327acf3be2bef9b8cb77337a Parents: 05b791a Author: madhawa <madhaw...@gmail.com> Authored: Fri Jun 23 11:43:42 2017 +0530 Committer: madhawa <madhaw...@gmail.com> Committed: Fri Jun 23 11:43:42 2017 +0530 ---------------------------------------------------------------------- .../gora/cassandra/bean/CassandraKey.java | 43 +++++++- .../gora/cassandra/bean/ClusterKeyField.java | 41 +++++++ .../apache/gora/cassandra/bean/KeySpace.java | 35 +++--- .../gora/cassandra/bean/PartitionKeyField.java | 51 +++++++++ .../gora/cassandra/store/CassandraMapping.java | 25 +++-- .../gora/cassandra/store/CassandraStore.java | 107 +++++++++++++++++-- .../src/test/conf/gora-cassandra-mapping.xml | 12 +-- 7 files changed, 272 insertions(+), 42 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/CassandraKey.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/CassandraKey.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/CassandraKey.java index c0adf2c..ca9657b 100644 --- a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/CassandraKey.java +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/CassandraKey.java @@ -17,8 +17,49 @@ package org.apache.gora.cassandra.bean; +import java.util.ArrayList; +import java.util.List; + /** * This Class represents the Cassandra Key. */ -public class CassandraKey { +public class CassandraKey{ + + private String name; + + private List<ClusterKeyField> clusterKeyFields; + + private List<PartitionKeyField> partitionKeyFields; + + + public CassandraKey(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public List<ClusterKeyField> getClusterKeyFields() { + return clusterKeyFields; + } + + public List<PartitionKeyField> getPartitionKeyFields() { + return partitionKeyFields; + } + + public void addPartitionKeyField(PartitionKeyField partitionKeyField) { + if(this.partitionKeyFields == null) { + this.partitionKeyFields = new ArrayList<>(); + } + this.partitionKeyFields.add(partitionKeyField); + } + + public void addClusterKeyField(ClusterKeyField clusterKeyField) { + if(this.clusterKeyFields == null) { + this.clusterKeyFields = new ArrayList<>(); + } + this.clusterKeyFields.add(clusterKeyField); + } + } http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/ClusterKeyField.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/ClusterKeyField.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/ClusterKeyField.java new file mode 100644 index 0000000..560b61c --- /dev/null +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/ClusterKeyField.java @@ -0,0 +1,41 @@ +/* + * 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.gora.cassandra.bean; + +/** + * This class represents Cassandra Clustering Key. + */ +public class ClusterKeyField extends Field { + + public enum Order { + DESC, + ASC, + } + + private Order order; + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + +} http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/KeySpace.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/KeySpace.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/KeySpace.java index b695782..709b53b 100644 --- a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/KeySpace.java +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/KeySpace.java @@ -25,6 +25,24 @@ import java.util.Map; * This class represents the Cassandra Keyspace. */ public class KeySpace { + + public enum PlacementStrategy { + SimpleStrategy, + NetworkTopologyStrategy, + } + + private String name; + + private PlacementStrategy placementStrategy; + + private Map<String, String> properties; + + private boolean durableWritesEnabled; + + private int replicationFactor; + + private Map<String, Integer> dataCenters; + public String getName() { return name; } @@ -49,21 +67,10 @@ public class KeySpace { this.dataCenters.put(key, value); } - private String name; - - private Map<String, String> properties; - - private boolean durableWritesEnabled; - public KeySpace() { this.properties = new HashMap<>(); } - public enum PlacementStrategy { - SimpleStrategy, - NetworkTopologyStrategy, - } - public void setPlacementStrategy(PlacementStrategy placementStrategy) { this.placementStrategy = placementStrategy; if(placementStrategy.equals(PlacementStrategy.NetworkTopologyStrategy) && this.dataCenters == null) { @@ -71,16 +78,10 @@ public class KeySpace { } } - private PlacementStrategy placementStrategy; - public void setReplicationFactor(int replicationFactor) { this.replicationFactor = replicationFactor; } - private int replicationFactor; - - private Map<String, Integer> dataCenters; - private List<String> tables; public void addProperty(String key, String value) { http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/PartitionKeyField.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/PartitionKeyField.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/PartitionKeyField.java new file mode 100644 index 0000000..a0d9c4c --- /dev/null +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/bean/PartitionKeyField.java @@ -0,0 +1,51 @@ +/* + * 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.gora.cassandra.bean; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class represents Cassandra Partition Key. + */ +public class PartitionKeyField extends Field { + + private boolean isComposite; + + private List<Field> fields; + + public boolean isComposite() { + return isComposite; + } + + public void setComposite(boolean composite) { + isComposite = composite; + if(isComposite && fields == null) { + fields = new ArrayList<>(); + } + } + + public void addField(Field field) { + this.fields.add(field); + } + + public List<Field> getFields() { + return fields; + } + +} http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraMapping.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraMapping.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraMapping.java index 4a67215..7acc99c 100644 --- a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraMapping.java +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraMapping.java @@ -17,6 +17,7 @@ package org.apache.gora.cassandra.store; +import org.apache.gora.cassandra.bean.CassandraKey; import org.apache.gora.cassandra.bean.Field; import org.apache.gora.cassandra.bean.KeySpace; @@ -26,10 +27,20 @@ import java.util.List; import java.util.Map; /** - * This class represents the Cassandra Mapping + * This class represents the Cassandra Mapping. */ public class CassandraMapping { + private CassandraKey cassandraKey; + + private Map<String, String> tableProperties; + + private KeySpace keySpace; + + private List<Field> fieldList; + + private String coreName; + public KeySpace getKeySpace() { return keySpace; } @@ -38,15 +49,17 @@ public class CassandraMapping { this.keySpace = keySpace; } - private KeySpace keySpace; - public List<Field> getFieldList() { return fieldList; } - private List<Field> fieldList; + public CassandraKey getCassandraKey() { + return cassandraKey; + } - private Map<String, String> tableProperties; + public void setCassandraKey(CassandraKey cassandraKey) { + this.cassandraKey = cassandraKey; + } public CassandraMapping() { this.fieldList = new ArrayList<>(); @@ -61,8 +74,6 @@ public class CassandraMapping { return coreName; } - private String coreName; - public void addCassandraField(Field field) { this.fieldList.add(field); } http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraStore.java ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraStore.java b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraStore.java index 20bf7f9..09123da 100644 --- a/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraStore.java +++ b/gora-cassandra-cql/src/main/java/org/apache/gora/cassandra/store/CassandraStore.java @@ -21,8 +21,7 @@ import com.datastax.driver.mapping.Mapper; import com.datastax.driver.mapping.MappingManager; import com.datastax.driver.core.*; import com.datastax.driver.core.policies.*; -import org.apache.gora.cassandra.bean.Field; -import org.apache.gora.cassandra.bean.KeySpace; +import org.apache.gora.cassandra.bean.*; import org.apache.gora.persistency.BeanFactory; import org.apache.gora.persistency.impl.PersistentBase; import org.apache.gora.query.PartitionQuery; @@ -115,12 +114,11 @@ public class CassandraStore<K, T extends PersistentBase> extends DataStoreBase<K CassandraMapping map = new CassandraMapping(); try { SAXBuilder builder = new SAXBuilder(); - Document doc = builder.build(getClass().getClassLoader() - .getResourceAsStream(filename)); + Document doc = builder.build(getClass().getClassLoader().getResourceAsStream(filename)); List<Element> keyspaces = doc.getRootElement().getChildren("keyspace"); - List<Element> classes = doc.getRootElement().getChildren("class"); + List<Element> keys = doc.getRootElement().getChildren("cassandraKey"); boolean classMatched = false; for (Element classElement : classes) { @@ -179,7 +177,7 @@ public class CassandraStore<K, T extends PersistentBase> extends DataStoreBase<K String keyspaceName = map.getProperty("keyspace"); if (keyspaceName != null) { - KeySpace keyspace = null; + KeySpace keyspace; for (Element keyspaceElement : keyspaces) { if (keyspaceName.equals(keyspaceElement.getAttributeValue("name"))) { keyspace = new KeySpace(); @@ -200,17 +198,17 @@ public class CassandraStore<K, T extends PersistentBase> extends DataStoreBase<K break; } } - Element placementStrategy = keyspaceElement.getChild("placementStrategy"); + Element placementStrategy = keyspaceElement.getChild("placementStrategy"); switch (KeySpace.PlacementStrategy.valueOf(placementStrategy.getAttributeValue("name"))) { case SimpleStrategy: keyspace.setPlacementStrategy(KeySpace.PlacementStrategy.SimpleStrategy); keyspace.setReplicationFactor(Integer.parseInt(placementStrategy.getAttributeValue("replication_factor"))); break; case NetworkTopologyStrategy: - List<Element> dataCenters = placementStrategy.getChildren("datacenter"); + List<Element> dataCenters = placementStrategy.getChildren("datacenter"); keyspace.setPlacementStrategy(KeySpace.PlacementStrategy.NetworkTopologyStrategy); - for(Element dataCenter : dataCenters) { - String dataCenterName = dataCenter.getAttributeValue("name"); + for (Element dataCenter : dataCenters) { + String dataCenterName = dataCenter.getAttributeValue("name"); Integer dataCenterReplicationFactor = Integer.valueOf(dataCenter.getAttributeValue("replication_factor")); keyspace.addDataCenter(dataCenterName, dataCenterReplicationFactor); } @@ -224,10 +222,97 @@ public class CassandraStore<K, T extends PersistentBase> extends DataStoreBase<K } + for (Element key : keys) { + if (keyClass.getName().equals(key.getAttributeValue("name"))) { + CassandraKey cassandraKey = new CassandraKey(keyClass.getName()); + Element partitionKeys = key.getChild("partitionKey"); + Element clusterKeys = key.getChild("clusterKey"); + List<Element> partitionKeyFields = partitionKeys.getChildren("field"); + List<Element> partitionCompositeKeyFields = partitionKeys.getChildren("compositeField"); + // process non composite partition keys + for (Element partitionKeyField : partitionKeyFields) { + PartitionKeyField fieldKey = new PartitionKeyField(); + List fieldAttributes = partitionKeyField.getAttributes(); + for (Object anAttributeList : fieldAttributes) { + Attribute attribute = (Attribute) anAttributeList; + String attributeName = attribute.getName(); + String attributeValue = attribute.getValue(); + switch (attributeName) { + case "name": + fieldKey.setFieldName(attributeValue); + break; + case "column": + fieldKey.setColumnName(attributeValue); + break; + default: + fieldKey.addProperty(attributeName, attributeValue); + break; + } + } + cassandraKey.addPartitionKeyField(fieldKey); + } + // process composite partitions keys + for (Element partitionCompositeKeyField : partitionCompositeKeyFields) { + PartitionKeyField compositeFieldKey = new PartitionKeyField(); + compositeFieldKey.setComposite(true); + List<Element> compositeKeyFields = partitionCompositeKeyField.getChildren("field"); + for (Element partitionKeyField : compositeKeyFields) { + PartitionKeyField fieldKey = new PartitionKeyField(); + List fieldAttributes = partitionKeyField.getAttributes(); + for (Object anAttributeList : fieldAttributes) { + Attribute attribute = (Attribute) anAttributeList; + String attributeName = attribute.getName(); + String attributeValue = attribute.getValue(); + switch (attributeName) { + case "name": + fieldKey.setFieldName(attributeValue); + break; + case "column": + fieldKey.setColumnName(attributeValue); + break; + default: + fieldKey.addProperty(attributeName, attributeValue); + break; + } + } + compositeFieldKey.addField(fieldKey); + } + cassandraKey.addPartitionKeyField(compositeFieldKey); + + } + + //process cluster keys + List<Element> clusterKeyFields = clusterKeys.getChildren("field"); + for (Element clusterKeyField : clusterKeyFields) { + ClusterKeyField keyField = new ClusterKeyField(); + List fieldAttributes = clusterKeyField.getAttributes(); + for (Object anAttributeList : fieldAttributes) { + Attribute attribute = (Attribute) anAttributeList; + String attributeName = attribute.getName(); + String attributeValue = attribute.getValue(); + switch (attributeName) { + case "name": + keyField.setFieldName(attributeValue); + break; + case "column": + keyField.setColumnName(attributeValue); + break; + case "order": + keyField.setOrder(ClusterKeyField.Order.valueOf(attributeValue.toUpperCase())); + break; + default: + keyField.addProperty(attributeName, attributeValue); + break; + } + } + cassandraKey.addClusterKeyField(keyField); + } + map.setCassandraKey(cassandraKey); + } + } } catch (Exception ex) { throw new IOException(ex); } - return map; } http://git-wip-us.apache.org/repos/asf/gora/blob/6617b0bb/gora-cassandra-cql/src/test/conf/gora-cassandra-mapping.xml ---------------------------------------------------------------------- diff --git a/gora-cassandra-cql/src/test/conf/gora-cassandra-mapping.xml b/gora-cassandra-cql/src/test/conf/gora-cassandra-mapping.xml index b039638..5f59ba8 100644 --- a/gora-cassandra-cql/src/test/conf/gora-cassandra-mapping.xml +++ b/gora-cassandra-cql/src/test/conf/gora-cassandra-mapping.xml @@ -71,7 +71,7 @@ <field name="id" column="srilankan" type="uuid" ttl="10"/> </class> - <class name="org.apache.gora.examples.generated.Employee" keyClass="org.apache.gora.examples.generated.SensorKey" keyspace="WebPage" + <class name="org.apache.gora.examples.generated.Employee" keyClass="org.apache.gora.examples.generated.WebPage" keyspace="WebPage" compactStorage="true" id="31323131"> <field name="lname" column="name" type="text" ttl="10" primarykey="true"/> <field name="fname" column="name" type="text" ttl="10"/> @@ -80,12 +80,12 @@ <field name="id" column="srilankan" type="uuid" ttl="10"/> </class> - <cassandraKey name="org.apache.gora.examples.generated.SensorKey"> + <cassandraKey name="org.apache.gora.examples.generated.WebPage"> <partitionKey> - <field composite="true"> - <column name="id" type=""/> - <column name="name" type=""/> - </field> + <compositeField> + <field name="id" type=""/> + <field name="name" type=""/> + </compositeField> <field name="sensorId" type="UTF8Type"/> <field name="year" type="IntegerType"/> </partitionKey>