This is an automated email from the ASF dual-hosted git repository.
dmagda pushed a commit to branch IGNITE-7595
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/IGNITE-7595 by this push:
new 0cb8389 Ported the Cassandra integration's documentation from
readme.io to the new docs engine
new fdef11c Merge remote-tracking branch 'origin/IGNITE-7595' into
IGNITE-7595
0cb8389 is described below
commit 0cb83898200e81c05fd6e90fb2b82473df3aba61
Author: Denis Magda <[email protected]>
AuthorDate: Wed Sep 30 16:39:41 2020 -0700
Ported the Cassandra integration's documentation from readme.io to the new
docs engine
---
docs/_data/toc.yaml | 10 +
.../cassandra/configuration.adoc | 574 +++++++++++++++++
.../cassandra/ddl-generator.adoc | 85 +++
.../cassandra/overview.adoc | 40 ++
.../cassandra/usage-examples.adoc | 677 +++++++++++++++++++++
docs/_docs/persistence/external-storage.adoc | 10 +-
6 files changed, 1391 insertions(+), 5 deletions(-)
diff --git a/docs/_data/toc.yaml b/docs/_data/toc.yaml
index c68e4e8..6bd41f0 100644
--- a/docs/_data/toc.yaml
+++ b/docs/_data/toc.yaml
@@ -421,6 +421,16 @@
url: extensions-and-integrations/streaming/zeromq-streamer
- title: Twitter Streamer
url: extensions-and-integrations/streaming/twitter-streamer
+ - title: Cassandra Integration
+ items:
+ - title: Overview
+ url: extensions-and-integrations/cassandra/overview
+ - title: Configuration
+ url: extensions-and-integrations/cassandra/configuration
+ - title: Usage Examples
+ url: extensions-and-integrations/cassandra/usage-examples
+ - title: DDL Generator
+ url: extensions-and-integrations/cassandra/ddl-generator
- title: C# and .NET Specific
items:
- title: Configuration Options
diff --git
a/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc
b/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc
new file mode 100644
index 0000000..d35d32d
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc
@@ -0,0 +1,574 @@
+= Ignite Cassandra Integration Configuration
+
+= Overview
+
+To setup Cassandra as a persistent store, you need to set `CacheStoreFactory`
for your Ignite caches to
+`org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory`.
+
+This could be done using Spring context configuration like this:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<bean id="ignite.cfg"
class="org.apache.ignite.configuration.IgniteConfiguration">
+ <property name="cacheConfiguration">
+ <list>
+ ...
+ <!-- Configuring persistence for "cache1" cache -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="cache1"/>
+ <!-- Tune on Read-Through and Write-Through mode -->
+ <property name="readThrough" value="true"/>
+ <property name="writeThrough" value="true"/>
+ <!-- Specifying CacheStoreFactory -->
+ <property name="cacheStoreFactory">
+ <bean
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+ <!-- Datasource configuration bean which is
responsible for Cassandra connection details -->
+ <property name="dataSourceBean"
value="cassandraDataSource"/>
+ <!-- Persistent settings bean which is responsible for
the details of how objects will be persisted to Cassandra -->
+ <property name="persistenceSettingsBean"
value="cache1_persistence_settings"/>
+ </bean>
+ </property>
+ </bean>
+ ...
+ </list>
+ ...
+ </property>
+</bean>
+----
+--
+
+There are two main properties which should be specified for
`CassandraCacheStoreFactory`:
+
+* `dataSourceBean` - instance of the
`org.apache.ignite.cache.store.cassandra.datasource.DataSource` class
responsible for
+all the aspects of Cassandra database connection (credentials, contact points,
read/write consistency level, load balancing policy and etc...)
+* `persistenceSettingsBean` - instance of the
`org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings`
+class responsible for all the aspects of how objects should be persisted into
Cassandra (keyspace and its options, table
+and its options, partition and cluster key options, POJO object fields
mapping, secondary indexes, serializer for BLOB objects and etc...)
+
+In the below section these two beans and their configuration settings will be
described in details.
+
+== DataSourceBean
+
+This bean stores all the details required for Cassandra database connection
and CRUD operations. In the table below you can find all the bean properties:
+
+[cols="20%,70%,10%",opts="header"]
+|===
+| Property | Description | Default
+| `user`| User name used to connect to Cassandra|
+| `password`| User password used to connect to Cassandra|
+| `credentials`| Credentials bean providing `username` and `password`|
+| `authProvider`| Use the specified AuthProvider when connecting to Cassandra.
Use this method when a custom authentication scheme is in place.|
+| `port`| Port to use to connect to Cassandra (if it's not provided in
connection point specification)|
+| `contactPoints`| Array of contact points (`hostaname:[port]`) to use for
Cassandra connection|
+| `maxSchemaAgreementWaitSeconds`| Maximum time to wait for schema agreement
before returning from a DDL query| `10` seconds
+| `protocolVersion`| Specifies what version of Cassandra driver protocol
should be used (could be helpful for backward compatibility with old versions
of Cassandra)| `3`
+| `compression`| Compression to use for the transport. Supported compressions:
`snappy`, `lz4`|
+| `useSSL`| Enables the use of SSL| `false`
+| `sslOptions`| Enables the use of SSL using the provided options|`false`
+| `collectMetrix`| Enables metrics collection|`false`
+| `jmxReporting`| Enables JMX reporting of the metrics|`false`
+| `fetchSize`| Specifies query fetch size. Fetch size controls how much
resulting rows will be retrieved simultaneously.|
+| `readConsistency`| Specifies consistency level for READ queries|
+| `writeConsistency`| Specifies consistency level for WRITE/DELETE/UPDATE
queries|
+| `loadBalancingPolicy`| Specifies load balancing policy to use|
`TokenAwarePolicy`
+| `reconnectionPolicy`| Specifies reconnection policy to use|
`ExponentialReconnectionPolicy`
+| `retryPolicy`| Specifies retry policy to use| `DefaultRetryPolicy`
+| `addressTranslater`| Specifies address translater to use|
`IdentityTranslater`
+| `speculativeExecutionPolicy`| Specifies speculative execution policy to use|
`NoSpeculativeExecutionPolicy`
+| `poolingOptions`| Specifies connection pooling options|
+| `socketOptions`| Specifies low-level socket options for the connections kept
to the Cassandra hosts|
+| `nettyOptions`| Hooks that allow clients to customize Cassandra driver's
underlying Netty layer|
+|===
+
+
+== PersistenceSettingsBean
+
+This bean stores all the details(keyspace, table, partition options, POJO
fields mapping and etc...) of how objects
+(keys and values) should be persisted into Cassandra database.
+
+The constructor of
`org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings`
allows to create such
+a bean from a string which contains XML configuration document of specific
structure (see below) or from the resource pointing to XML document.
+
+Here is the generic example of an XML configuration document (*persistence
descriptor*) which specifies how Ignite cache
+keys and values should be serialized/deserialized to/from Cassandra:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<!--
+Root container for persistence settings configuration.
+
+Note: required element
+
+Attributes:
+ 1) keyspace [required] - specifies keyspace for Cassandra tables which
should be used to store key/value pairs
+ 2) table [required] - specifies Cassandra table which should be used to
store key/value pairs
+ 3) ttl [optional] - specifies expiration period for the table rows (in
seconds)
+-->
+<persistence keyspace="my_keyspace" table="my_table" ttl="86400">
+ <!--
+ Specifies Cassandra keyspace options which should be used to create
provided keyspace if it doesn't exist.
+
+ Note: optional element
+ -->
+ <keyspaceOptions>
+ REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+ AND DURABLE_WRITES = true
+ </keyspaceOptions>
+
+ <!--
+ Specifies Cassandra table options which should be used to create provided
table if it doesn't exist.
+
+ Note: optional element
+ -->
+ <tableOptions>
+ comment = 'A most excellent and useful table'
+ AND read_repair_chance = 0.2
+ </tableOptions>
+
+ <!--
+ Specifies persistent settings for Ignite cache keys.
+
+ Note: required element
+
+ Attributes:
+ 1) class [required] - java class name for Ignite cache key
+ 2) strategy [required] - one of three possible persistent strategies:
+ a) PRIMITIVE - stores key value as is, by mapping it to Cassandra
table column with corresponding type.
+ Should be used only for simple java types (int, long, String,
double, Date) which could be mapped
+ to corresponding Cassadra types.
+ b) BLOB - stores key value as BLOB, by mapping it to Cassandra
table column with blob type.
+ Could be used for any java object. Conversion of java object
to BLOB is handled by "serializer"
+ which could be specified in serializer attribute (see below).
+ c) POJO - stores each field of an object as a column having
corresponding type in Cassandra table.
+ Provides ability to utilize Cassandra secondary indexes for
object fields.
+ 3) serializer [optional] - specifies serializer class for BLOB strategy.
Shouldn't be used for PRIMITIVE and
+ POJO strategies. Available implementations:
+ a)
org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses
standard Java
+ serialization framework
+ b)
org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
+ serialization framework
+ 4) column [optional] - specifies column name for PRIMITIVE and BLOB
strategies where to store key value.
+ If not specified column having 'key' name will be used. Shouldn't be
used for POJO strategy.
+ -->
+ <keyPersistence class="org.mycompany.MyKeyClass" strategy="..."
serializer="..." column="...">
+ <!--
+ Specifies partition key fields if POJO strategy used.
+
+ Note: optional element, only required for POJO strategy in case you
want to manually specify
+ POJO fields to Cassandra columns mapping, instead of relying on
dynamic discovering of
+ POJO fields and mapping them to the same columns of Cassandra
table.
+ -->
+ <partitionKey>
+ <!--
+ Specifies mapping from POJO field to Cassandra table column.
+
+ Note: required element
+
+ Attributes:
+ 1) name [required] - POJO field name
+ 2) column [optional] - Cassandra table column name. If not
specified lowercase
+ POJO field name will be used.
+ -->
+ <field name="companyCode" column="company" />
+ ...
+ ...
+ </partitionKey>
+
+ <!--
+ Specifies cluster key fields if POJO strategy used.
+
+ Note: optional element, only required for POJO strategy in case you
want to manually specify
+ POJO fields to Cassandra columns mapping, instead of relying on
dynamic discovering of
+ POJO fields and mapping them to the same columns of Cassandra
table.
+ -->
+ <clusterKey>
+ <!--
+ Specifies mapping from POJO field to Cassandra table column.
+
+ Note: required element
+
+ Attributes:
+ 1) name [required] - POJO field name
+ 2) column [optional] - Cassandra table column name. If not
specified lowercase
+ POJO field name will be used.
+ 3) sort [optional] - specifies sort order (asc or desc)
+ -->
+ <field name="personNumber" column="number" sort="desc"/>
+ ...
+ ...
+ </clusterKey>
+ </keyPersistence>
+
+ <!--
+ Specifies persistent settings for Ignite cache values.
+
+ Note: required element
+
+ Attributes:
+ 1) class [required] - java class name for Ignite cache value
+ 2) strategy [required] - one of three possible persistent strategies:
+ a) PRIMITIVE - stores key value as is, by mapping it to Cassandra
table column with corresponding type.
+ Should be used only for simple java types (int, long, String,
double, Date) which could be mapped
+ to corresponding Cassadra types.
+ b) BLOB - stores key value as BLOB, by mapping it to Cassandra
table column with blob type.
+ Could be used for any java object. Conversion of java object
to BLOB is handled by "serializer"
+ which could be specified in serializer attribute (see below).
+ c) POJO - stores each field of an object as a column having
corresponding type in Cassandra table.
+ Provides ability to utilize Cassandra secondary indexes for
object fields.
+ 3) serializer [optional] - specifies serializer class for BLOB strategy.
Shouldn't be used for PRIMITIVE and
+ POJO strategies. Available implementations:
+ a)
org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses
standard Java
+ serialization framework
+ b)
org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
+ serialization framework
+ 4) column [optional] - specifies column name for PRIMITIVE and BLOB
strategies where to store value.
+ If not specified column having 'value' name will be used. Shouldn't be
used for POJO strategy.
+ -->
+ <valuePersistence class="org.mycompany.MyValueClass" strategy="..."
serializer="..." column="">
+ <!--
+ Specifies mapping from POJO field to Cassandra table column.
+
+ Note: required element
+
+ Attributes:
+ 1) name [required] - POJO field name
+ 2) column [optional] - Cassandra table column name. If not
specified lowercase
+ POJO field name will be used.
+ 3) static [optional] - boolean flag which specifies that
column is static withing a given partition
+ 4) index [optional] - boolean flag specifying that secondary
index should be created for the field
+ 5) indexClass [optional] - custom index java class name if you
want to use custom index
+ 6) indexOptions [optional] - custom index options
+ -->
+ <field name="firstName" column="first_name" static="..." index="..."
indexClass="..." indexOptions="..."/>
+ ...
+ ...
+ </valuePersistence>
+</persistence>
+----
+--
+
+Below are provided all the details about persistence descriptor configuration
and its elements:
+
+=== persistence
+
+[CAUTION]
+====
+[discrete]
+=== ! Required Element
+Root container for persistence settings configuration.
+====
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+| `keyspace`| yes | Keyspace for Cassandra tables which should be used to
store key/value pairs. If keyspace doesn't
+exist it will be created (if specified Cassandra account has appropriate
permissions).
+| `table`| no | Cassandra table which should be used to store key/value pairs.
If table doesn't exist it will be created
+(if specified Cassandra account has appropriate permissions). If table name
doesn't specified Ignite cache name will be used as a table name.
+| `ttl`| no | Expiration period for the table rows (in seconds).
+|===
+
+In the next chapters you'll find what child elements could be placed inside
persistence settings container.
+
+=== keyspaceOptions
+
+[NOTE]
+====
+[discrete]
+=== Optional Element
+Options to create Cassandra keyspace specified in the `keyspace` attribute of
persistence settings container.
+====
+
+Keyspace will be created only if it doesn't exist and if an account used to
connect to Cassandra has appropriate permissions.
+
+The text specified in this XML element is just a chunk of
+http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_keyspace_r.html[CREATE
KEYSPACE, window=_blank] Cassandra DDL statement which goes after *WITH*
keyword.
+
+=== tableOptions
+
+[NOTE]
+====
+[discrete]
+=== Optional Element
+Options to create Cassandra table specified in the table attribute of
persistence settings container.
+====
+
+A table will be created only if it doesn't exist and if an account used to
connect to Cassandra has appropriate permissions.
+
+The text specified in this XML element is just a chunk of
+http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_table_r.html[CREATE
TABLE, window=_blank] Cassandra DDL statement which goes after *WITH* keyword.
+
+=== keyPersistence
+
+[CAUTION]
+====
+[discrete]
+=== ! Required Element
+Persistent settings for Ignite cache keys.
+====
+
+These settings specify how key objects from Ignite cache should be
stored/loaded to/from Cassandra table:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+
+| `class`
+| yes
+| Java class name for Ignite cache keys.
+
+| `strategy`
+| yes
+| Specifies one of three possible persistent strategies (see below) which
controls how object should be persisted/loaded to/from Cassandra table.
+
+| `serializer`
+| no
+| Serializer class for BLOB strategy (see below for available
implementations). Shouldn't be used for PRIMITIVE and POJO strategies.
+
+| `column`
+| no
+| Column name for PRIMITIVE and BLOB strategies where to store key. If not
specified, column having 'key' name will be
+used. Attribute shouldn't be specified for POJO strategy.
+|===
+
+Persistence strategies:
+
+[cols="1,3",opts="header"]
+|===
+| Name | Description
+
+| `PRIMITIVE`
+| Stores object as is, by mapping it to Cassandra table column with
corresponding type. Should be used only for simple java types
+(int, long, String, double, Date) which could be directly mapped to
corresponding Cassadra types. Use this
+https://docs.datastax.com/en/developer/java-driver/4.4/manual/core/#cql-to-java-type-mapping[link,
window=_blank] to figure out Java to Cassandra types mapping.
+
+| `BLOB`
+| Stores object as BLOB, by mapping it to Cassandra table column with blob
type. Could be used for any java object.
+Conversion of java object to BLOB is handled by "serializer" which could be
specified in serializer attribute of *keyPersistence* container.
+
+| `POJO`
+| Stores each field of an object as a column having corresponding type in
Cassandra table. Provides ability to utilize
+Cassandra secondary indexes for object fields. Could be used only for POJO
objects following Java Beans convention and
+having their fields of
https://docs.datastax.com/en/developer/java-driver/4.4/manual/core/#cql-to-java-type-mapping[simple
java type which could be directly mapped to corresponding Cassandra types,
window=_blank].
+|===
+
+Available serializer implementations:
+
+[cols="1,3",opts="header"]
+|===
+| Class | Description
+
+| `org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer`
+| Uses standard Java serialization framework
+
+| `org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer`
+| Uses Kryo serialization framework
+|===
+
+If you are using `PRIMITIVE` or `BLOB` persistence strategy you don't need to
specify internal elements of `keyPersistence`
+tag, cause the idea of these two strategies is that the whole object should be
persisted into one column of Cassandra table
+(which could be specified by `column` attribute).
+
+If you are using the `POJO` persistence strategy you have two option:
+
+* Leave `keyPersistence` tag empty - in a such case, all the fields of POJO
object class will be detected automatically using such rules:
+ ** Only fields having simple java types which could be directly mapped to
+http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate
Cassandra types, window=_blank]
+will be detected.
+ ** Fields discovery mechanism takes into account `@QuerySqlField` annotation:
+ *** If `name` attribute is specified it will be used as a column name for
Cassandra table. Otherwise field name in a lowercase will be used as a column
name.
+ *** If `descending` attribute is specified for a field mapped to *cluster
key* column, it will be used to set sort order for the column.
+ ** Fields discovery mechanism takes into account `@AffinityKeyMapped`
annotation. All the fields marked by this annotation
+will be treated as
http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[partition
key, window=_blank]
+fields (in an order as they are declared in a class). All other fields will be
treated as
+http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[cluster
key] fields.
+ ** If there are no fields annotated with `@AffinityKeyMapped` all the
discovered fields will be treated as
+http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[partition
key, window=_blank] fields.
+* Specify persistence details inside `keyPersistence` tag - in such case, you
have to specify *partition key* fields
+mapping to Cassandra table columns inside `partitionKey` tag. This tag is used
just as a container for mapping settings
+and doesn't have any attributes. Optionally (if you are going to use cluster
key) you can also specify *cluster key*
+fields mapping to appropriate Cassandra table columns inside `clusterKey` tag.
This tag is used just as a container for
+mapping settings and doesn't have any attributes.
+
+Next two sections are providing a detailed specification for `partition` and
`cluster` key fields mappings (which makes
+sense if you choose the second option from the list above).
+
+=== partitionKey
+
+[NOTE]
+====
+[discrete]
+=== Optional Element
+Container for `field` elements specifying Cassandra partition key.
+====
+
+Defines the Ignite cache KEY object fields (inside it), which should be used
as a *partition key* fields in Cassandra
+table and specifies fields mappings to table columns.
+
+Mappings are specified by using `<field>` tag having such attributes:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+
+| `name`
+| yes
+| POJO object field name.
+
+| `column`
+| no
+| Cassandra table column name. If not specified lowercase POJO field name will
be used.
+|===
+
+=== clusterKey
+
+[NOTE]
+====
+[discrete]
+=== Optional Element
+Container for `field` elements specifying Cassandra cluster key.
+====
+
+Defines the Ignite cache KEY object fields (inside it), which should be used
as a *cluster key* fields in Cassandra
+table and specifies fields mappings to table columns.
+
+Mapping are specified by using `<field>` tag having such attributes:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+
+| `name`
+| yes
+| POJO object field name.
+
+| `column`
+| no
+| Cassandra table column name. If not specified lowercase POJO field name will
be used.
+
+
+| `sort`
+| no
+| Specifies sort order for the field (`asc` or `desc`).
+|===
+
+=== valuePersistence
+
+[CAUTION]
+====
+[discrete]
+=== ! Required Element
+Persistent settings for Ignite cache values.
+====
+
+These settings specify how value objects from Ignite cache should be
stored/loaded to/from Cassandra table. The settings attributes
+look very similar to corresponding settings for Ignite cache keys:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+
+| `class`
+| yes
+| Java class name for Ignite cache values.
+
+| `strategy`
+| yes
+| Specifies one of three possible persistent strategies (see below) which
controls how object should be persisted/loaded to/from Cassandra table.
+
+| `serializer`
+| no
+| Serializer class for BLOB strategy (see below for available
implementations). Shouldn't be used for `PRIMITIVE` and `POJO` strategies.
+
+| `column`
+| no
+| Column name for `PRIMITIVE` and `BLOB` strategies where to store value. If
not specified, column having `value` name will be used.
+Attribute shouldn't be specified for POJO strategy.
+|===
+
+Persistence strategies (same as for key persistence settings):
+
+[cols="1,3",opts="header"]
+|===
+| Name | Description
+
+| `PRIMITIVE`
+| Stores object as is, by mapping it to Cassandra table column with
corresponding type. Should be used only for simple java types
+(int, long, String, double, Date) which could be directly mapped to
corresponding Cassadra types. Use this
+http://docs.datastax.com/en/developer/java-driver/2.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[link,
window=_blank] to figure out Java to Cassandra types mapping.
+
+| `BLOB`
+| Stores object as `BLOB`, by mapping it to Cassandra table column with blob
type. Could be used for any java object. Conversion of
+java object to `BLOB` is handled by "serializer" which could be specified in
serializer attribute of `keyPersistence` container.
+
+| `POJO`
+| Stores each field of an object as a column having a corresponding type in
Cassandra table. Provides ability to utilize Cassandra
+secondary indexes for object fields. Could be used only for POJO objects
following Java Beans convention and having their fields
+of
http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[simple
java type which could be directly mapped to corresponding Cassandra types,
window=_blank].
+|===
+
+Available serializer implementations (same as for key persistence settings):
+
+[cols="1,3",opts="header"]
+|===
+| Class | Description
+
+| `org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer`
+| Uses standard Java serialization framework.
+
+| `org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer`
+| Uses Kryo serialization framework.
+|===
+
+If you are using `PRIMITIVE` or `BLOB` persistence strategy you don't need to
specify internal elements of `valuePersistence`
+tag, cause the idea of these two strategies is that the whole object should be
persisted into one column of Cassandra table
+(which could be specified by `column` attribute).
+
+If you are using `POJO` persistence strategy you have two option (similar to
the same options for keys):
+
+* Leave `valuePersistence` tag empty - in such a case, all the fields of POJO
object class will be detected automatically using such rules:
+ ** Only fields having simple java types which could be directly mapped to
+http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate
Cassandra types, window=_blank] will be detected.
+ ** Fields discovery mechanism takes into account `@QuerySqlField` annotation:
+ *** If `name` attribute is specified it will be used as a column name for
Cassandra table. Otherwise, field name in a lower case will be used as a column
name.
+ *** If `index` attribute is specified, secondary index will be created for a
corresponding column in Cassandra table (if such table doesn't exist).
+* Specify persistence details inside `valuePersistence` tag - in such a case,
you have to specify your POJO fields mapping to Cassandra table columns
+inside `valuePersistence` tag.
+
+If you selected the second option from the list above, you have to use
`<field>` tag to specify POJO fields to Cassandra
+table columns mapping. The tag has following attributes:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| Attribute | Required | Description
+
+| `name`
+| yes
+| POJO object field name.
+
+| `column`
+| no
+| Cassandra table column name. If not specified lowercase POJO field name will
be used.
+
+| `static`
+| no
+| Boolean flag which specifies that column is static withing a given partition.
+
+| `index`
+| no
+| Boolean flag specifying that secondary index should be created for the field.
+
+| `indexClass`
+| no
+| Custom index java class name, in case you want to use custom index.
+
+| `indexOptions`
+| no
+| Custom index options.
+|===
diff --git
a/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc
b/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc
new file mode 100644
index 0000000..4935648
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc
@@ -0,0 +1,85 @@
+= DDL Generator
+
+== Overview
+
+One of the benefits of the Ignite Cassandra integration is that you don't need
to care about Cassandra DDL syntax for
+table creation and Java to Cassandra type mapping details.
+
+You just need to create an XML configuration which specifies how Ignite cache
keys and values should be serialized/deserialized to/from Cassandra.
+Based on this settings all the absent Cassandra keyspaces and tables will be
created automatically. The only requirement for all this "magic" to work:
+
+[CAUTION]
+====
+[discrete]
+===
+In connection settings for Cassandra, you should specify user having enough
permissions to create keyspaces/tables
+====
+
+However, for some of the deployments it's not possible because of a very
strict security policy. Thus the only solution in
+a such situation is to provide DDL scripts for DevOps team to create all the
necessary Cassandra keyspaces/tables in advance.
+
+That's the exact use-case for DDL generator utility that generates DDLs from
+link:extensions-and-integrations/cassandra/configuration#persistencesettingsbean[PersistenceSettingsBean
settings].
+
+Below is a sample syntax for the Cassandra DDL generation:
+
+[tabs]
+--
+tab:Shell[]
+[source, shell]
+----
+java org.apache.ignite.cache.store.cassandra.utils.DDLGenerator
/opt/dev/ignite/persistence-settings-1.xml
/opt/dev/ignite/persistence-settings-2.xml
+----
+--
+
+The generated DDL can look as follows:
+
+[tabs]
+--
+tab:Generated Cassandra DDL[]
+[source, sql]
+----
+-------------------------------------------------------------
+DDL for keyspace/table from file: /opt/dev/ignite/persistence-settings-1.xml
+-------------------------------------------------------------
+
+create keyspace if not exists test1
+with replication = {'class' : 'SimpleStrategy', 'replication_factor' : 3} and
durable_writes = true;
+
+create table if not exists test1.primitive_test1
+(
+ key int,
+ value int,
+ primary key ((key))
+);
+
+-------------------------------------------------------------
+DDL for keyspace/table from file: /opt/dev/ignite/persistence-settings-2.xml
+-------------------------------------------------------------
+
+create keyspace if not exists test1
+with REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3} AND
DURABLE_WRITES = true;
+
+create table if not exists test1.pojo_test3
+(
+ company text,
+ department text,
+ number int,
+ first_name text,
+ last_name text,
+ age int,
+ married boolean,
+ height bigint,
+ weight float,
+ birth_date timestamp,
+ phones blob,
+ primary key ((company, department), number)
+)
+with comment = 'A most excellent and useful table' AND read_repair_chance =
0.2 and clustering order by (number desc);
+----
+--
+
+Just don't forget to set the `CLASSPATH` environment variable correctly:
+
+. Include the jar file for Ignite Cassandra module
(`ignite-cassandra-<version-number>.jar`) in your `CLASSPATH`.
+. If you are using `POJO` persistence strategy for some of your custom java
classes you need to include jars with these classes in your CLASSPATH as well.
diff --git a/docs/_docs/extensions-and-integrations/cassandra/overview.adoc
b/docs/_docs/extensions-and-integrations/cassandra/overview.adoc
new file mode 100644
index 0000000..cbe3935
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/overview.adoc
@@ -0,0 +1,40 @@
+= Apache Cassandra Acceleration With Apache Ignite
+
+== Overview
+
+The Ignite Cassandra integration implements the
link:persistence/external-storage#overview[CacheStore] interface allowing
+to deploy Ignite as a high-performance caching layer on top of Cassandra.
+
+Some observations in regards to the integration:
+
+. The integration uses Cassandra
http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous
queries, window=_blank]
+for `CacheStore` batch operations such as such as `loadAll()`, `writeAll()`
and `deleteAll()` to provide extremely high performance.
+. The integration automatically creates all necessary tables (and keyspaces)
in Cassandra if they are absent. Also, it
+automatically detects all the necessary fields for Ignite key-value tuples
that will be stored as POJOs, and creates an
+appropriate table structure. Thus you don't need to care about the Cassandra
DDL syntax for table creation and Java to
+Cassandra type mapping details.
+. You can optionally specify the settings (replication factor, replication
strategy, bloom filter and etc.) for Cassandra
+tables and keyspaces which should be created.
+. Combines functionality of BLOB and POJO storage, allowing to specify how you
prefer to store (as a BLOB or as a POJO)
+key-value tuples from your Ignite cache.
+. Supports standard
https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html[Java,
window=_blank] and
+https://github.com/EsotericSoftware/kryo[Kryo, window=_blank] serialization
for key-values which should be stored as BLOBs in Cassandra
+. Supports Cassandra
http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_index_r.html[secondary
indexes, window=_blank] (including custom indexes)
+through persistence configuration settings for particular Ignite cache or such
settings could be detected automatically
+if you configured link:SQL/indexes#configuring-indexes-using-annotations[SQL
Indexes by Annotations] by using `@QuerySqlField(index = true)` annotation
+. Supports sort order for Cassandra cluster key fields through persistence
configuration settings or such settings could be
+detected automatically if you are using `@QuerySqlField(descending = true)`
annotation.
+. Supports link:data-modeling/affinity-collocation[affinity co-location] for
the POJO key classes having one of their fields
+annotated by `@AffinityKeyMapped`. In such a way, key-values tuples which were
stored on one node in an Ignite cache will
+be also stored (co-located) on one node in Cassandra.
+
+[CAUTION]
+====
+[discrete]
+=== Ignite SQL Queries and Cassandra
+Note that in order to execute SQL queries you need to have all the data loaded
from Cassandra into an Ignite cluster.
+The Ignite SQL engine doesn't assumes that all the records are available in
memory and won't try to query Cassandra.
+
+An alternative would be to use Ignite Native Persistence - a distributed,
ACID, and SQL-compliant disk store that allows
+performing SQL queries on the data stored in-memory as well as on disk.
+====
diff --git
a/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc
b/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc
new file mode 100644
index 0000000..894228b
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc
@@ -0,0 +1,677 @@
+= Ignite Cassandra Integration Usage Examples
+
+== Overview
+
+As described in
link:extensions-and-integrations/cassandra/configuration[configuration
section], to configure Cassandra
+as a cache store you need to set `CacheStoreFactory` for your Ignite caches to
`org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory`.
+
+Below is an example of a typical configuration for Ignite cache to use
Cassandra as a cache store. We will go step-by-step
+through all the configuration items, further down. The example is taken from
the unit tests resource file
+`store/src/test/resources/org/apache/ignite/tests/persistence/blob/ignite-config.xml`
of the Cassandra module source code.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <!-- Cassandra connection settings -->
+ <import
resource="classpath:org/apache/ignite/tests/cassandra/connection-settings.xml"
/>
+
+ <!-- Persistence settings for 'cache1' -->
+ <bean id="cache1_persistence_settings"
class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
+ <constructor-arg type="org.springframework.core.io.Resource"
value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml"
/>
+ </bean>
+
+ <!-- Persistence settings for 'cache2' -->
+ <bean id="cache2_persistence_settings"
class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
+ <constructor-arg type="org.springframework.core.io.Resource"
value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-3.xml"
/>
+ </bean>
+
+ <!-- Ignite configuration -->
+ <bean id="ignite.cfg"
class="org.apache.ignite.configuration.IgniteConfiguration">
+ <property name="cacheConfiguration">
+ <list>
+ <!-- Configuring persistence for "cache1" cache -->
+ <bean
class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="cache1"/>
+ <property name="readThrough" value="true"/>
+ <property name="writeThrough" value="true"/>
+ <property name="cacheStoreFactory">
+ <bean
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+ <property name="dataSourceBean"
value="cassandraAdminDataSource"/>
+ <property name="persistenceSettingsBean"
value="cache1_persistence_settings"/>
+ </bean>
+ </property>
+ </bean>
+
+ <!-- Configuring persistence for "cache2" cache -->
+ <bean
class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="cache2"/>
+ <property name="readThrough" value="true"/>
+ <property name="writeThrough" value="true"/>
+ <property name="cacheStoreFactory">
+ <bean
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+ <property name="dataSourceBean"
value="cassandraAdminDataSource"/>
+ <property name="persistenceSettingsBean"
value="cache2_persistence_settings"/>
+ </bean>
+ </property>
+ </bean>
+ </list>
+ </property>
+
+ <!-- Explicitly configure TCP discovery SPI to provide list of initial
nodes. -->
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <!--
+ Ignite provides several options for automatic
discovery that can be used
+ instead os static IP based discovery. For information
on all options refer
+ to our documentation:
http://apacheignite.readme.io/docs/cluster-config
+ -->
+ <!-- Uncomment static IP finder to enable static-based
discovery of initial nodes. -->
+ <!--<bean
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
+ <bean
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with
actual host IP address. -->
+ <value>127.0.0.1:47500..47509</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
+----
+--
+
+In the specified example we have two Ignite caches configured: `cache1` and
`cache2`. So lets look at the configuration details.
+
+Lets start from the cache configuration details. They are pretty similar for
both caches (`cache1` and `cache2`) and looks like that:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="cache1"/>
+ <property name="readThrough" value="true"/>
+ <property name="writeThrough" value="true"/>
+ <property name="cacheStoreFactory">
+ <bean
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+ <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+ <property name="persistenceSettingsBean"
value="cache1_persistence_settings"/>
+ </bean>
+ </property>
+</bean>
+----
+--
+
+First of all we can see that `read-through` and `write-through` options are
enabled:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="readThrough" value="true"/>
+<property name="writeThrough" value="true"/>
+----
+--
+
+which is required for Ignite cache, if you plan to use a persistent store for
cache entries which expired.
+
+You can optionally specify the `write-behind` setting if you prefer persistent
store to be updated asynchronously:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="readThrough" value="true"/>
+<property name="writeThrough" value="true"/>
+----
+--
+
+The next important thing is `CacheStoreFactory` configuration:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="cacheStoreFactory">
+ <bean
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+ <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+ <property name="persistenceSettingsBean"
value="cache1_persistence_settings"/>
+ </bean>
+</property>
+----
+--
+
+You should use
`org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory` as a
`CacheStoreFactory` for your
+Ignite caches to utilize Cassandra as a persistent store. For
`CassandraCacheStoreFactory` you should specify two required properties:
+
+* `dataSourceBean` - name of the Spring bean, which specifies all the details
about Cassandra database connection.
+
+* `persistenceSettingsBean` - name of the Spring bean, which specifies all the
details about how objects should be persisted into Cassandra database.
+
+In the specified example `cassandraAdminDataSource` is a data source bean,
which is imported into Ignite cache config file using this directive:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<import
resource="classpath:org/apache/ignite/tests/cassandra/connection-settings.xml"
/>
+----
+--
+
+and `cache1_persistence_settings` is a persistence settings bean, which is
defined in Ignite cache config file using such directive:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<bean id="cache1_persistence_settings"
class="org.apache.ignite.cache.store.cassandra.utils.persistence.KeyValuePersistenceSettings">
+ <constructor-arg type="org.springframework.core.io.Resource"
value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml"
/>
+</bean>
+----
+--
+
+Now lets look at the specification of `cassandraAdminDataSource` from
`store/src/test/resources/org/apache/ignite/tests/cassandra/connection-settings.xml`
+test resource.
+
+Specifically,`CassandraAdminCredentials` and `CassandraRegularCredentials` are
classes which extend
+`org.apache.ignite.cache.store.cassandra.datasource.Credentials`. You are
welcome to implement these classes and reference them afterwards.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="cassandraAdminCredentials"
class="org.my.project.CassandraAdminCredentials"/>
+ <bean id="cassandraRegularCredentials"
class="org.my.project.CassandraRegularCredentials"/>
+
+ <bean id="loadBalancingPolicy"
class="com.datastax.driver.core.policies.TokenAwarePolicy">
+ <constructor-arg
type="com.datastax.driver.core.policies.LoadBalancingPolicy">
+ <bean class="com.datastax.driver.core.policies.RoundRobinPolicy"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="contactPoints"
class="org.apache.ignite.tests.utils.CassandraHelper"
factory-method="getContactPointsArray"/>
+
+ <bean id="cassandraAdminDataSource"
class="org.apache.ignite.cache.store.cassandra.datasource.DataSource">
+ <property name="credentials" ref="cassandraAdminCredentials"/>
+ <property name="contactPoints" ref="contactPoints"/>
+ <property name="readConsistency" value="ONE"/>
+ <property name="writeConsistency" value="ONE"/>
+ <property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
+ </bean>
+
+ <bean id="cassandraRegularDataSource"
class="org.apache.ignite.cache.store.cassandra.datasource.DataSource">
+ <property name="credentials" ref="cassandraRegularCredentials"/>
+ <property name="contactPoints" ref="contactPoints"/>
+ <property name="readConsistency" value="ONE"/>
+ <property name="writeConsistency" value="ONE"/>
+ <property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
+ </bean>
+</beans>
+----
+--
+
+For more details about Cassandra data source connection configuration visit
the link:extensions-and-integrations/cassandra/configuration[integration
configuration page].
+
+Finally, the last piece which wasn't still described is persistence settings
configuration. Lets look at the
+`cache1_persistence_settings` from the
`org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml` test
resource.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="blob_test1">
+ <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE" />
+ <valuePersistence strategy="BLOB"/>
+</persistence>
+----
+--
+
+In the configuration above, we can see that Cassandra `test1.blob_test1` table
will be used to store key/value objects for
+**cache1** cache. Key objects of the cache will be stored as **integer** in
`key` column. Value objects of the cache will be
+stored as **blob** in `value` column. For more information about persistence
settings configuration visit the
+link:extensions-and-integrations/cassandra/configuration[integration
configuration page].
+
+Next sections will provide examples of persistence settings configuration for
different kind of persistence strategies
+(see more details about persistence strategies on the
link:extensions-and-integrations/cassandra/configuration[integration
configuration page].
+
+== Example 1
+
+Persistence setting for Ignite cache with keys of `Integer` type to be
persisted as `int` in Cassandra and values of
+`String` type to be persisted as `text` in Cassandra.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+ <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE"
column="my_key"/>
+ <valuePersistence class="java.lang.String" strategy="PRIMITIVE" />
+</persistence>
+----
+--
+
+Keys will be stored in `my_key` column. Values will be stored in `value`
column (which is used by default if `column` attribute wasn't specified).
+
+== Example 2
+
+Persistence setting for Ignite cache with keys of `Integer` type to be
persisted as `int` in Cassandra and values of `any`
+type (you don't need to specify the type for **BLOB** persistence strategy) to
be persisted as `blob` in Cassandra.
+The only solution for this situation is to store value as a `BLOB` in
Cassandra table.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+ <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE" />
+ <valuePersistence strategy="BLOB"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column (which is used by default if `column`
attribute wasn't specified). Values will be stored in `value` column.
+
+== Example 3
+
+Persistence setting for Ignite cache with keys of `Integer` type and values of
**any** type, both to be persisted as `BLOB` in Cassandra.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+ <!-- By default Java standard serialization is going to be used -->
+ <keyPersistence class="java.lang.Integer"
+ strategy="BLOB"/>
+
+ <!-- Kryo serialization specified to be used -->
+ <valuePersistence class="org.apache.ignite.tests.pojos.Person"
+ strategy="BLOB"
+
serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column having `blob` type and using
+https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html[Java standard
serialization, window=_blank]. Values will be stored in
+`value` column having `blob` type and using
https://github.com/EsotericSoftware/kryo[Kryo serialization, window=_blank].
+
+== Example 4
+
+Persistence setting for Ignite cache with keys of `Integer` type to be
persisted as `int` in Cassandra and values of custom
+POJO `org.apache.ignite.tests.pojos.Person` type to be dynamically analyzed
and persisted into a set of table columns,
+so that each POJO field will be mapped to appropriate table column. For more
details about dynamic POJO fields discovery
+refer to
link:extensions-and-integrations/cassandra/configuration#persistencesettingsbean[PersistenceSettingsBean]
documentation section.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+ <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE"/>
+ <valuePersistence class="org.apache.ignite.tests.pojos.Person"
strategy="POJO"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column having `int` type.
+
+Now lets imagine that the `org.apache.ignite.tests.pojos.Person` class has
such an implementation:
+
+[tabs]
+--
+tab:Java[]
+[source, java]
+----
+public class Person {
+ private String firstName;
+ private String lastName;
+ private int age;
+ private boolean married;
+ private long height;
+ private float weight;
+ private Date birthDate;
+ private List<String> phones;
+
+ public void setFirstName(String name) {
+ firstName = name;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setLastName(String name) {
+ lastName = name;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setMarried(boolean married) {
+ this.married = married;
+ }
+
+ public boolean getMarried() {
+ return married;
+ }
+
+ public void setHeight(long height) {
+ this.height = height;
+ }
+
+ public long getHeight() {
+ return height;
+ }
+
+ public void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ public float getWeight() {
+ return weight;
+ }
+
+ public void setBirthDate(Date date) {
+ birthDate = date;
+ }
+
+ public Date getBirthDate() {
+ return birthDate;
+ }
+
+ public void setPhones(List<String> phones) {
+ this.phones = phones;
+ }
+
+ public List<String> getPhones() {
+ return phones;
+ }
+}
+----
+--
+
+In this case Ignite cache values of the `org.apache.ignite.tests.pojos.Person`
type will be persisted into a set of
+Cassandra table columns using such dynamically configured mapping rule:
+
+[opts="header"]
+|===
+| POJO field | Table column | Column type
+| firstName | firstname | text
+| lastName | lastname | text
+| age | age | int
+| married | married | boolean
+| height | height | bigint
+| weight | weight | float
+| birthDate | birthdate | timestamp
+|===
+
+As you can see from the table above, `phones` field will not be persisted into
table. That's because it's not of simple
+java type which could be directly mapped to
http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate,
window=_blank] Cassandra type.
+Such kind of fields could be persisted into Cassandra only if you manually
specify all mapping details for the object type
+and if field type itself is implementing `java.io.Serializable` interface. In
a such case field will be persisted into a
+separate table column as `blob`. See more details in the next example.
+
+== Example 5
+
+Persistence setting for Ignite cache with keys of custom POJO
`org.apache.ignite.tests.pojos.PersonId` and values of
+custom POJO `org.apache.ignite.tests.pojos.Person` types, both to be persisted
into a set of table columns based on
+manually specified mapping rules.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table" ttl="86400">
+ <!-- Cassandra keyspace options which should be used to create provided
keyspace if it doesn't exist -->
+ <keyspaceOptions>
+ REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+ AND DURABLE_WRITES = true
+ </keyspaceOptions>
+
+ <!-- Cassandra table options which should be used to create provided table
if it doesn't exist -->
+ <tableOptions>
+ comment = 'A most excellent and useful table'
+ AND read_repair_chance = 0.2
+ </tableOptions>
+
+ <!-- Persistent settings for Ignite cache keys -->
+ <keyPersistence class="org.apache.ignite.tests.pojos.PersonId"
strategy="POJO">
+ <!-- Partition key fields if POJO strategy used -->
+ <partitionKey>
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="companyCode" column="company" />
+ <field name="departmentCode" column="department" />
+ </partitionKey>
+
+ <!-- Cluster key fields if POJO strategy used -->
+ <clusterKey>
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="personNumber" column="number" sort="desc"/>
+ </clusterKey>
+ </keyPersistence>
+
+ <!-- Persistent settings for Ignite cache values -->
+ <valuePersistence class="org.apache.ignite.tests.pojos.Person"
+ strategy="POJO"
+
serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer">
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="firstName" column="first_name" />
+ <field name="lastName" column="last_name" />
+ <field name="age" />
+ <field name="married" index="true"/>
+ <field name="height" />
+ <field name="weight" />
+ <field name="birthDate" column="birth_date" />
+ <field name="phones" />
+ </valuePersistence>
+</persistence>
+----
+--
+
+These persistence settings looks rather complicated. Lets go step by step and
analyse them.
+
+Lets first look at the root tag:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table" ttl="86400">
+----
+--
+
+It specifies that Ignite cache keys and values should be stored in
`test1.my_table` table and that data in each row
+http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_expire_c.html[expires,
window=_blank] after `86400` sec which is `24` hours.
+
+Then we can see the advanced settings for Cassandra keyspace. The setting will
be used to create keyspace if it's not exist.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<keyspaceOptions>
+ REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+ AND DURABLE_WRITES = true
+</keyspaceOptions>
+----
+--
+
+Then by analogy to keyspace setting we can see table advanced setting, which
will be used only for table creation.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<tableOptions>
+ comment = 'A most excellent and useful table'
+ AND read_repair_chance = 0.2
+</tableOptions>
+----
+--
+
+Next section specifies how Ignite cache keys should be persisted:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<keyPersistence class="org.apache.ignite.tests.pojos.PersonId" strategy="POJO">
+ <!-- Partition key fields if POJO strategy used -->
+ <partitionKey>
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="companyCode" column="company" />
+ <field name="departmentCode" column="department" />
+ </partitionKey>
+
+ <!-- Cluster key fields if POJO strategy used -->
+ <clusterKey>
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="personNumber" column="number" sort="desc"/>
+ </clusterKey>
+</keyPersistence>
+----
+--
+
+Lets assume that `org.apache.ignite.tests.pojos.PersonId` has such
implementation:
+
+[tabs]
+--
+tab:Java[]
+[source, java]
+----
+public class PersonId {
+ private String companyCode;
+ private String departmentCode;
+ private int personNumber;
+
+ public void setCompanyCode(String code) {
+ companyCode = code;
+ }
+
+ public String getCompanyCode() {
+ return companyCode;
+ }
+
+ public void setDepartmentCode(String code) {
+ departmentCode = code;
+ }
+
+ public String getDepartmentCode() {
+ return departmentCode;
+ }
+
+ public void setPersonNumber(int number) {
+ personNumber = number;
+ }
+
+ public int getPersonNumber() {
+ return personNumber;
+ }
+}
+----
+--
+
+In such case Ignite cache keys of `org.apache.ignite.tests.pojos.PersonId`
type will be persisted into a set of Cassandra
+table columns representing `PARTITION` and `CLUSTER` key using this mapping
rule:
+
+[opts="header"]
+|===
+| POJO field | Table column | Column type
+| companyCode | company | text
+| departmentCode | department | text
+| personNumber | number | int
+|===
+
+In addition to that, combination of columns `(company, department)` will be
used as Cassandra `PARTITION` key and column
+`number` will be used as a `CLUSTER` key sorted in descending order.
+
+Finally lets move to the last section, which specifies persistence settings
for Ignite cache values:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<valuePersistence class="org.apache.ignite.tests.pojos.Person"
+ strategy="POJO"
+
serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer">
+ <!-- Mapping from POJO field to Cassandra table column -->
+ <field name="firstName" column="first_name" />
+ <field name="lastName" column="last_name" />
+ <field name="age" />
+ <field name="married" index="true"/>
+ <field name="height" />
+ <field name="weight" />
+ <field name="birthDate" column="birth_date" />
+ <field name="phones" />
+</valuePersistence>
+----
+--
+
+Lets assume `that org.apache.ignite.tests.pojos.Person` class has the same
implementation like in
link:extensions-and-integrations/cassandra/usage-examples#example-4[Example 4].
+In this case Ignite cache values of `org.apache.ignite.tests.pojos.Person`
type will be persisted into a set of Cassandra
+table columns using such mapping rule:
+
+[opts="header"]
+|===
+| POJO field | Table column | Column type
+| firstName | first_name | text
+| lastName | last_name | text
+| age | age | int
+| married | married | boolean
+| height | height | bigint
+| weight | weight | float
+| birthDate | birth_date | timestamp
+| phones | phones | blob
+|===
+
+Comparing to
link:extensions-and-integrations/cassandra/usage-examples#example-4[Example 4]
we can see that now `phones`
+field will be serialized to `phones` column of `blob` type using
https://github.com/EsotericSoftware/kryo[Kryo, window=_blank] serializer.
+In addition to that, Cassandra secondary index will be created for the
`married` column.
diff --git a/docs/_docs/persistence/external-storage.adoc
b/docs/_docs/persistence/external-storage.adoc
index b163ab8..47188ad2 100644
--- a/docs/_docs/persistence/external-storage.adoc
+++ b/docs/_docs/persistence/external-storage.adoc
@@ -196,12 +196,12 @@ CAUTION: Even though Ignite supports distributed
transactions, it doesn't make y
=== Cassandra Integration
-Ignite provides an out-of-the-box implementation of `CacheStore` that enables
you to use Apache Cassandra as a persistent storage. This implementation
utilizes Cassandra's
link:http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous
queries] to provide high performance batch operations such as `loadAll()`,
`writeAll()` and `deleteAll()`, and automatically creates all necessary tables
and namespaces in Cassandra.
+Ignite provides an out-of-the-box implementation of `CacheStore` that enables
you to use Apache Cassandra as a persistent
+storage. This implementation utilizes Cassandra's
link:http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous
queries, window=_blank]
+to provide high performance batch operations such as `loadAll()`, `writeAll()`
and `deleteAll()`, and automatically creates
+all necessary tables and namespaces in Cassandra.
-////
-TODO
-Refer to the dedicated section on Cassandra integration for more information.
-////
+Refer to link:extensions-and-integrations/cassandra/overview[this
documentation section] for configuration and usage guidelines.
////
== Implementing Custom CacheStore