diff --git a/README.adoc b/README.adoc
index 9b6e8cb76..86b7321de 100644
--- a/README.adoc
+++ b/README.adoc
@@ -140,12 +140,16 @@ For non-blocking reactive API use `ReactiveAerospikeRepository`.
=== 3. Configuration
In order to configure Spring Data Aerospike you will need to create a configuration class that extends
-`AbstractAerospikeDataConfiguration`, defines the relevant Spring Data Repositories via `@EnableAerospikeRepositories`
-annotation and overrides `getHosts()` and `nameSpace()` methods with the required connection details.
+`AbstractAerospikeDataConfiguration` and defines the relevant Spring Data Repositories via `@EnableAerospikeRepositories`
+annotation.
-NOTE: You can optionally override xref:#configure-data-settings[`configureDataSettings`] method of `AbstractAerospikeDataConfiguration` to further customize your configuration.
+To set the connection details you can either override `getHosts()` and `nameSpace()` methods
+of the `AbstractAerospikeDataConfiguration` class or define `spring-data-aerospike.connection.hosts` and
+`spring-data-aerospike.connection.namespace` in `application.properties` file.
-Here is a simple example of a configuration class that sets up a connection to a local Aerospike instance:
+NOTE: You can further customize your configuration by changing other xref:#configuration[`settings`].
+
+Here is a simple example of a configuration class that sets up a connection to a local Aerospike DB instance:
[source,java]
----
diff --git a/pom.xml b/pom.xml
index 9f5a425f1..9be433e02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
UTF-83.2.13.2.1
+ 3.2.13.2.04.1.03.3.0
@@ -183,6 +184,12 @@
spring-data-keyvalue${springdata.keyvalue}
+
+ org.springframework.boot
+ spring-boot
+ ${springdata.spring-boot}
+ compile
+ com.aerospikeaerospike-client
diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc
index 3243869d8..223357471 100644
--- a/src/main/asciidoc/index.adoc
+++ b/src/main/asciidoc/index.adoc
@@ -39,7 +39,7 @@ include::reference/template.adoc[]
include::reference/secondary-indexes.adoc[]
include::reference/indexed-annotation.adoc[]
include::reference/caching.adoc[]
-include::reference/configure-data-settings.adoc[]
+include::reference/configuration.adoc[]
include::spring-data-commons-docs/dependencies.adoc[]
include::spring-data-commons-docs/auditing.adoc[]
diff --git a/src/main/asciidoc/reference/aerospike-object-mapping.adoc b/src/main/asciidoc/reference/aerospike-object-mapping.adoc
index 213ef580b..f0cf95473 100644
--- a/src/main/asciidoc/reference/aerospike-object-mapping.adoc
+++ b/src/main/asciidoc/reference/aerospike-object-mapping.adoc
@@ -49,7 +49,7 @@ The following outlines what field will be mapped to the '_id' document field:
The following outlines what type of conversion, if any, will be done on the property mapped to the _id document field.
-* By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configure-data-settings.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
+* By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configuration.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
* If no field named "id" is present in the Java class then an implicit '_id' file will be generated by the driver but not mapped to a property or field of the Java class.
When querying and updating `AerospikeTemplate` will use the converter to handle conversions of the `Query` and `Update` objects that correspond to the above rules for saving documents so field names and types used in your queries will be able to match what is in your domain classes.
diff --git a/src/main/asciidoc/reference/caching.adoc b/src/main/asciidoc/reference/caching.adoc
index 7f1d965d1..bf76b03b6 100644
--- a/src/main/asciidoc/reference/caching.adoc
+++ b/src/main/asciidoc/reference/caching.adoc
@@ -206,7 +206,7 @@ public class UserController {
=== Add @EnableCaching
-==== SimpleSpringbootAerospikeCacheApplication
+==== SimpleSpringBootAerospikeCacheApplication
Add `@EnableCaching` to the class that contains the main method.
@@ -214,9 +214,9 @@ Add `@EnableCaching` to the class that contains the main method.
----
@EnableCaching
@SpringBootApplication
-public class SimpleSpringbootAerospikeCacheApplication {
+public class SimpleSpringBootAerospikeCacheApplication {
public static void main(String[] args) {
- SpringApplication.run(SimpleSpringbootAerospikeCacheApplication.class, args);
+ SpringApplication.run(SimpleSpringBootAerospikeCacheApplication.class, args);
}
}
----
@@ -252,7 +252,7 @@ aql> select * from test
+-----+-----------+----------+-------------+-------------------------------------+
| @user_key | name | @_class | email | age |
+-----+-----------+----------+-------------+-------------------------------------+
-| "1" | "guthrie" | "com.aerospike.cache.simplespringbootaerospikecache.objects.User" | "guthriegovan@gmail.com" | 35 |
+| "1" | "guthrie" | "com.aerospike.cache.simpleSpringBootAerospikeCache.objects.User" | "guthriegovan@gmail.com" | 35 |
+-----+-----------+----------+-------------+-------------------------------------+
----
@@ -315,6 +315,6 @@ aql> select * from test
+-----+-----------+----------+-------------+-------------------------------------+
| @user_key | name | @_class | email | age |
+-----+-----------+----------+-------------+-------------------------------------+
-| "1" | "jimmy page" | "com.aerospike.cache.simplespringbootaerospikecache.objects.User" | "jimmy@gmail.com" | 77 |
+| "1" | "jimmy page" | "com.aerospike.cache.simpleSpringBootAerospikeCache.objects.User" | "jimmy@gmail.com" | 77 |
+-----+-----------+----------+-------------+-------------------------------------+
----
diff --git a/src/main/asciidoc/reference/configuration.adoc b/src/main/asciidoc/reference/configuration.adoc
new file mode 100644
index 000000000..18be5b007
--- /dev/null
+++ b/src/main/asciidoc/reference/configuration.adoc
@@ -0,0 +1,398 @@
+[[configuration]]
+= Configuration
+
+Configuration parameters can be set in a standard `application.properties` file using `spring-data-aerospike.*` prefix
+or by overriding configuration from `AbstractAerospikeDataConfiguration` class.
+
+[[configuration.application-properties]]
+== Application.properties
+
+Here is an example:
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.connection.hosts=localhost:3000
+spring-data-aerospike.connection.namespace=test
+spring-data-aerospike.data.scans-enabled=false
+spring-data-aerospike.data.send-key=true
+spring-data-aerospike.data.create-indexes-on-startup=true
+spring-data-aerospike.data.index-cache-refresh-seconds=3600
+spring-data-aerospike.data.server-version-refresh-seconds=3600
+spring-data-aerospike.data.query-max-records=10000
+spring-data-aerospike.data.batch-write-size=100
+spring-data-aerospike.data.keep-original-key-types=false
+----
+
+Configuration class:
+
+[source, java]
+----
+@Configuration
+@EnableAerospikeRepositories(basePackageClasses = {TestRepository.class})
+public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
+
+}
+----
+
+In this case extending `AbstractAerospikeDataConfiguration` class is required to enable repositories.
+
+[[configuration.overriding-configuration]]
+== Overriding configuration
+
+Configuration can also be set by overriding `getHosts()`, `nameSpace()` and `configureDataSettings()` methods of the `AbstractAerospikeDataConfiguration` class.
+
+Here is an example:
+
+[source,java]
+----
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+ @Override
+ protected Collection getHosts() {
+ return Collections.singleton(new Host("localhost", 3000));
+ }
+
+ @Override
+ protected String nameSpace() {
+ return "test";
+ }
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setScansEnabled(false);
+ aerospikeDataSettings.setCreateIndexesOnStartup(true);
+ aerospikeDataSettings.setIndexCacheRefreshSeconds(3600);
+ aerospikeDataSettings.setServerVersionRefreshSeconds(3600);
+ aerospikeDataSettings.setQueryMaxRecords(10000L);
+ aerospikeDataSettings.setBatchWriteSize(100);
+ aerospikeDataSettings.setKeepOriginalKeyTypes(false);
+ }
+}
+----
+
+NOTE: Return values of `getHosts()`, `nameSpace()` and `configureDataSettings()` methods
+of the `AbstractAerospikeDataConfiguration` class have precedence over the parameters
+set via application.properties.
+
+[[configuration.parameters]]
+== Configuration Parameters
+
+[[configuration.hosts]]
+=== hosts
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.connection.hosts=hostname1:3001, hostname2:tlsName2:3002
+----
+
+A String of hosts separated by `,` in form of `hostname1[:tlsName1][:port1],...`
+
+IP addresses must be given in one of the following formats:
+
+[source,text]
+----
+IPv4: xxx.xxx.xxx.xxx
+IPv6: [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
+IPv6: [xxxx::xxxx]
+----
+
+IPv6 addresses must be enclosed by brackets. tlsName is optional.
+
+NOTE: Another way of defining hosts is overriding the `getHosts()` method.
+It has precedence over `hosts` parameter from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+ @Override
+ protected Collection getHosts() {
+ return Collections.singleton(new Host("hostname1", 3001));
+ }
+}
+----
+
+*Default:* `null`.
+
+[[configuration.namespace]]
+=== namespace
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.connection.namespace=test
+----
+
+Aerospike DB namespace.
+
+NOTE: Another way of defining hosts is overriding the `nameSpace()` method.
+It has precedence over `namespace` parameter from application.properties.
+Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+ @Override
+ protected String nameSpace() {
+ return "test";
+ }
+}
+----
+
+NOTE: To use multiple namespaces it is required to override `nameSpace()` and `AerospikeTemplate` for each
+configuration class per namespace.
+See https://github.com/aerospike-examples/spring-data-multiple-namespaces-example[multiple namespaces example]
+for implementation details.
+
+*Default:* `null`.
+
+[[configuration.scans-enabled]]
+=== scansEnabled
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.scans-enabled=false
+----
+
+A scan can be an expensive operation as all records in the set must be read by the Aerospike server,
+and then the condition is applied to see if they match.
+
+Due to the cost of performing this operation, scans from Spring Data Aerospike are disabled by default.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setScansEnabled(false);
+ }
+}
+----
+
+NOTE: Once this flag is enabled, scans run whenever needed with no warnings. This may or may not be optimal
+in a particular use case.
+
+*Default:* `false`.
+
+[[configuration.create-indexes-on-startup]]
+=== createIndexesOnStartup
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.create-indexes-on-startup=true
+----
+
+Create secondary indexes specified using `@Indexed` annotation on startup.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setCreateIndexesOnStartup(true);
+ }
+}
+----
+
+*Default*: `true`.
+
+[[configuration.index-cache-refresh-frequency-seconds]]
+=== indexCacheRefreshSeconds
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.index-cache-refresh-seconds=3600
+----
+
+Automatically refresh indexes cache every seconds.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setIndexCacheRefreshSeconds(3600);
+ }
+}
+----
+
+*Default*: `3600`.
+
+[[configuration.server-version-refresh-frequency-seconds]]
+=== serverVersionRefreshSeconds
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.server-version-refresh-seconds=3600
+----
+
+Automatically refresh cached server version every seconds.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setServerVersionRefreshSeconds(3600);
+ }
+}
+----
+
+*Default*: `3600`.
+
+[[configuration.query-max-records]]
+=== queryMaxRecords
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.query-max-records=10000
+----
+
+Limit amount of results returned by server. Non-positive value means no limit.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setQueryMaxRecords(10000L);
+ }
+}
+----
+
+*Default*: `10 000`.
+
+[[configuration.batch-write-size]]
+=== batchWriteSize
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.batch-write-size=100
+----
+
+Maximum batch size for batch write operations. Non-positive value means no limit.
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setBatchWriteSize(100);
+ }
+}
+----
+
+*Default*: `100`.
+
+[[configuration.keep-original-key-types]]
+=== keepOriginalKeyTypes
+
+[source,properties]
+----
+# application.properties
+spring-data-aerospike.data.keep-original-key-types=false
+----
+
+Define how `@Id` fields (primary keys) and `Map` keys are stored in the Aerospike database:
+`false` - always as `String`, `true` - preserve original type if supported.
+
+[width="100%",cols="<20%,<30%,<30%",options="header",]
+|===
+|`@Id` field type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true`
+|`long` |`String` | `long`
+|`int` |`String` | `long`
+|`String` |`String` | `String`
+|`byte[]` |`String` | `byte[]`
+|other types |`String` | `String`
+|===
+
+NOTE: If `@Id` field's type cannot be persisted as is, it must be convertible to `String` and will be stored
+in the database as such, then converted back to the original type when the object is read.
+This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
+
+[width="100%",cols="<20%,<30%,<30%",options="header",]
+|===
+|`Map` key type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true`
+|`long` |`String` | `long`
+|`int` |`String` | `long`
+|`double` |`String` | `double`
+|`String` |`String` | `String`
+|`byte[]` |`String` | `byte[]`
+|other types |`String` | `String`
+|===
+
+NOTE: Another way of defining the parameter is overriding the `configureDataSettings()` method.
+It has precedence over reading from application.properties. Here is an example:
+
+[source,java]
+----
+// overriding method
+@EnableAerospikeRepositories(basePackageClasses = TestRepository.class)
+class ApplicationConfig extends AbstractAerospikeDataConfiguration {
+
+
+ @Override
+ public void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
+ aerospikeDataSettings.setKeepOriginalKeyTypes(false);
+ }
+}
+----
+
+*Default*: `false` (store keys only as `String`).
+
diff --git a/src/main/asciidoc/reference/configure-data-settings.adoc b/src/main/asciidoc/reference/configure-data-settings.adoc
deleted file mode 100644
index 0122b2e2b..000000000
--- a/src/main/asciidoc/reference/configure-data-settings.adoc
+++ /dev/null
@@ -1,117 +0,0 @@
-[[configure-data-settings]]
-= Configure Data Settings
-
-The `AbstractAerospikeDataConfiguration` class exposes a number of beans that Spring Data Aerospike uses internally. User can optionally override `configureDataSettings` method to customize configuration.
-
-Here is an example:
-
-[source,java]
-----
-@EnableAerospikeRepositories(basePackageClasses = PersonRepository.class)
-class ApplicationConfig extends AbstractAerospikeDataConfiguration {
-
- @Override
- protected Collection getHosts() {
- return Collections.singleton(new Host("localhost", 3000));
- }
-
- @Override
- protected String nameSpace() {
- return "test";
- }
-
- @Override
- protected void configureDataSettings(AerospikeDataSettings.AerospikeDataSettingsBuilder builder) {
- builder.createIndexesOnStartup(true);
- builder.indexCacheRefreshSeconds(3600);
- builder.queryMaxRecords(10000L);
- }
-}
-----
-
-[[configure-data-settings.parameters]]
-== Configuration Parameters
-
-[[configure-data-settings.scans-enabled]]
-=== scansEnabled
-
-A scan can be an expensive operation as all records in the set must be read by the Aerospike server, and then the condition is applied to see if they match.
-
-Due to the cost of performing this operation, scans from Spring Data Aerospike are disabled by default.
-
-NOTE: Once this flag is enabled, scans run whenever needed with no warnings. This may or may not be optimal in a particular use case.
-
-*Default:* `false`.
-
-[[configure-data-settings.send-key]]
-=== sendKey
-
-Send user defined key in addition to hash digest on both reads and writes. If the key is sent on write, it will be stored with the record on the server.
-
-Default: `false` (do not send the user defined key).
-
-[[configure-data-settings.create-indexes-on-startup]]
-=== createIndexesOnStartup
-
-Create secondary indexes specified using `@Indexed` annotation on startup.
-
-*Default*: `true`.
-
-[[configure-data-settings.index-cache-refresh-frequency-seconds]]
-=== indexCacheRefreshSeconds
-
-Automatically refresh indexes cache every seconds.
-
-*Default*: `3600`.
-
-[[configure-data-settings.server-version-refresh-frequency-seconds]]
-=== serverVersionRefreshSeconds
-
-Automatically refresh cached server version every seconds.
-
-*Default*: `3600`.
-
-[[configure-data-settings.query-max-records]]
-=== queryMaxRecords
-
-Limit amount of results returned by server. Non-positive value means no limit.
-
-*Default*: `10 000`.
-
-[[configure-data-settings.batch-write-size]]
-=== batchWriteSize
-
-Maximum batch size for batch write operations. Non-positive value means no limit.
-
-*Default*: `100`.
-
-[[configure-data-settings.keep-original-key-types]]
-=== keepOriginalKeyTypes
-
-Define how `@Id` fields (primary keys) and `Map` keys are stored in the Aerospike database: `false` - always as `String`, `true` - preserve original type if supported.
-
-[width="100%",cols="<20%,<30%,<30%",options="header",]
-|===
-|`@Id` field type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true`
-|`long` |`String` | `long`
-|`int` |`String` | `long`
-|`String` |`String` | `String`
-|`byte[]` |`String` | `byte[]`
-|other types |`String` | `String`
-|===
-
-NOTE: If `@Id` field's type cannot be persisted as is, it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
-
-[width="100%",cols="<20%,<30%,<30%",options="header",]
-|===
-|`Map` key type |keepOriginalKeyTypes = `false` |keepOriginalKeyTypes = `true`
-|`long` |`String` | `long`
-|`int` |`String` | `long`
-|`double` |`String` | `double`
-|`String` |`String` | `String`
-|`byte[]` |`String` | `byte[]`
-|other types |`String` | `String`
-|===
-
-*Default*: `false` (store keys only as `String`).
-
diff --git a/src/main/asciidoc/reference/indexed-annotation.adoc b/src/main/asciidoc/reference/indexed-annotation.adoc
index 838883a96..934185b08 100644
--- a/src/main/asciidoc/reference/indexed-annotation.adoc
+++ b/src/main/asciidoc/reference/indexed-annotation.adoc
@@ -148,5 +148,6 @@ So the following will be true:
|a.dd.[1].{#0} |[mapKey("a"), mapKey("dd"),listIndex(1), mapRank(0)] |y
|===
-NOTE: There are relevant configuration parameters in AerospikeDataSettings:
-xref:#configure-data-settings.create-indexes-on-startup[create indexes on startup] and xref:#configure-data-settings.index-cache-refresh-frequency-seconds[indexes cache refresh frequency].
+NOTE: There are relevant configuration parameters:
+xref:#configuration.create-indexes-on-startup[create indexes on startup] and
+xref:#configuration.index-cache-refresh-frequency-seconds[indexes cache refresh frequency].
diff --git a/src/main/asciidoc/reference/installation-and-usage.adoc b/src/main/asciidoc/reference/installation-and-usage.adoc
index 0af6ef3cd..c703f0d23 100644
--- a/src/main/asciidoc/reference/installation-and-usage.adoc
+++ b/src/main/asciidoc/reference/installation-and-usage.adoc
@@ -50,7 +50,9 @@ implementation group: 'com.aerospike', name: 'spring-data-aerospike', version: '
== Connecting to Aerospike DB
-Configuring Spring Data Aerospike is easy with the help of the `AbstractAerospikeDataConfiguration` class.
+There are two ways of configuring a basic connection to Aerospike DB.
+
+* Overriding `getHosts()` and `nameSpace()` methods of the `AbstractAerospikeDataConfiguration` class:
[source, java]
----
@@ -61,7 +63,6 @@ public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
protected Collection getHosts() {
return Collections.singleton(new Host("localhost", 3000));
}
-
@Override
protected String nameSpace() {
return "test";
@@ -69,11 +70,32 @@ public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
}
----
-`@Configuration` tells Spring that this class contains configuration data, and `@EnableAerospikeRepositories` activates Aerospike repositories that can be used for data access. The parameter to this annotation tells Spring Data Aerospike where to look for the repositories. This can be a list of package names as strings using the `basePackages` value, or a list of classes through the `basePackageClass` value. If the latter is used (as in this example), the class is used to determine which package to scan, and all repositories in that package will be available for use. More details on repositories are below.
+* Using `application.properties`:
+
+Basic configuration in this case requires enabling repositories and then setting `hosts` and `namespace` in the `application.properties` file.
+
+[source, java]
+----
+@Configuration
+@EnableAerospikeRepositories(basePackageClasses = { PersonRepository.class})
+public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
+
+}
+----
+
+In `application.properties`:
+
+[source, properties]
+----
+# application.properties
+spring-data-aerospike.hosts=localhost:3000
+spring-data-aerospike.namespace=test
+----
-The primary information required by this configuration is how to connect to the cluster, provided through the `getHosts` and `nameSpace` calls.
+NOTE: Return values of `getHosts()` and `nameSpace()` methods of the `AbstractAerospikeDataConfiguration` class
+have precedence over `hosts` and `namespace` parameters set via application.properties.
-NOTE: You can optionally override xref:#configure-data-settings[`configureDataSettings`] method of `AbstractAerospikeDataConfiguration` to customize your configuration.
+For more detailed information see xref:#configuration[Configuration].
== Creating Functionality
@@ -156,6 +178,6 @@ aql> select * from test.Person where pk = "1"
NOTE: The fully qualified path of the class is listed in each record. This is needed to instantiate the class correctly, especially in cases when the compile-time type and runtime type of the object differ. For example, where a field is declared as a super class but the instantiated class is a subclass.
-NOTE: By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configure-data-settings.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
+NOTE: By default, the type of the field annotated with `@id` is turned into a `String` to be stored in Aerospike database. If the original type cannot be persisted (see xref:#configuration.keep-original-key-types[keepOriginalKeyTypes] for details), it must be convertible to `String` and will be stored in the database as such, then converted back to the original type when the object is read. This is transparent to the application but needs to be considered if using external tools like `AQL` to view the data.
diff --git a/src/main/asciidoc/reference/scan-operation.adoc b/src/main/asciidoc/reference/scan-operation.adoc
index 22371ae53..1e2681621 100644
--- a/src/main/asciidoc/reference/scan-operation.adoc
+++ b/src/main/asciidoc/reference/scan-operation.adoc
@@ -1,36 +1,20 @@
[[scan-operation]]
= Scan Operation
-A scan can be an expensive operation as all records in the set must be read by the Aerospike server, and then the condition is applied to see if they match.
+A scan can be an expensive operation as all records in the set must be read by the Aerospike server,
+and then the condition is applied to see if they match.
Due to the cost of performing this operation, scans from Spring Data Aerospike are disabled by default.
== Enabling Scan
-If the cost of the scans is acceptable to an organization, they can be enabled by setting xref:#configure-data-settings.scans-enabled[`scansEnabled`] to `true` in `AerospikeDataSettings`.
+If the cost of the scans is acceptable to an organization, they can be enabled by setting
+xref:#configuration.scans-enabled[`scansEnabled`] parameter to `true`.
-One way to do this is to create a custom bean which overrides the default settings:
-
-[source,java]
+[source,properties]
----
-@Configuration
-@EnableAerospikeRepositories(basePackageClasses = { PersonRepository.class})
-public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
- @Override
- protected Collection getHosts() {
- return Collections.singleton(new Host("localhost", 3000));
- }
-
- @Override
- protected String nameSpace() {
- return "test";
- }
-
- @Bean
- public AerospikeDataSettings aerospikeDataSettings() {
- return AerospikeDataSettings.builder().scansEnabled(true).build();
- }
-}
+spring-data-aerospike.scans-enabled=true
----
-NOTE: Once this flag is enabled, scans run whenever needed with no warnings. This may or may not be optimal in a particular use case.
+NOTE: Once this flag is enabled, scans run whenever needed with no warnings.
+This may or may not be optimal in a particular use case.
diff --git a/src/main/asciidoc/reference/secondary-indexes.adoc b/src/main/asciidoc/reference/secondary-indexes.adoc
index bba594078..3fb93b767 100644
--- a/src/main/asciidoc/reference/secondary-indexes.adoc
+++ b/src/main/asciidoc/reference/secondary-indexes.adoc
@@ -125,6 +125,7 @@ public List findByFirstName(String firstName);
In this case `firstName` is not marked as `@Indexed`, so SpringData Aerospike is not instructed to create an index on it.
Hence, it will scan the repository (a costly operation that could be avoided by using an index).
-NOTE: There are relevant configuration parameters in AerospikeDataSettings:
-xref:#configure-data-settings.create-indexes-on-startup[create indexes on startup] and xref:#configure-data-settings.index-cache-refresh-frequency-seconds[indexes cache refresh frequency].
+NOTE: There are relevant configuration parameters:
+xref:#configuration.create-indexes-on-startup[create indexes on startup] and
+xref:#configuration.index-cache-refresh-frequency-seconds[indexes cache refresh frequency].
diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java
index f16b35393..1f69fee27 100644
--- a/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java
+++ b/src/main/java/org/springframework/data/aerospike/config/AbstractAerospikeDataConfiguration.java
@@ -45,20 +45,22 @@ public AerospikeTemplate aerospikeTemplate(IAerospikeClient aerospikeClient,
AerospikeMappingContext aerospikeMappingContext,
AerospikeExceptionTranslator aerospikeExceptionTranslator,
QueryEngine queryEngine, IndexRefresher indexRefresher,
- ServerVersionSupport serverVersionSupport) {
- return new AerospikeTemplate(aerospikeClient, nameSpace(), mappingAerospikeConverter,
- aerospikeMappingContext, aerospikeExceptionTranslator, queryEngine, indexRefresher, serverVersionSupport);
+ ServerVersionSupport serverVersionSupport,
+ AerospikeSettings settings) {
+ return new AerospikeTemplate(aerospikeClient, settings.getConnectionSettings().getNamespace(),
+ mappingAerospikeConverter, aerospikeMappingContext, aerospikeExceptionTranslator, queryEngine,
+ indexRefresher, serverVersionSupport);
}
@Bean(name = "aerospikeQueryEngine")
public QueryEngine queryEngine(IAerospikeClient aerospikeClient,
StatementBuilder statementBuilder,
- FilterExpressionsBuilder filterExpressionsBuilder) {
+ FilterExpressionsBuilder filterExpressionsBuilder, AerospikeSettings settings) {
QueryEngine queryEngine = new QueryEngine(aerospikeClient, statementBuilder, filterExpressionsBuilder);
- boolean scansEnabled = aerospikeDataSettings().isScansEnabled();
+ boolean scansEnabled = settings.getDataSettings().isScansEnabled();
log.debug("AerospikeDataSettings.scansEnabled: {}", scansEnabled);
queryEngine.setScansEnabled(scansEnabled);
- long queryMaxRecords = aerospikeDataSettings().getQueryMaxRecords();
+ long queryMaxRecords = settings.getDataSettings().getQueryMaxRecords();
log.debug("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords);
queryEngine.setQueryMaxRecords(queryMaxRecords);
return queryEngine;
@@ -68,9 +70,8 @@ public QueryEngine queryEngine(IAerospikeClient aerospikeClient,
public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(
ObjectProvider aerospikeMappingContext,
AerospikeIndexResolver aerospikeIndexResolver,
- ObjectProvider template)
- {
- boolean indexesOnStartup = aerospikeDataSettings().isCreateIndexesOnStartup();
+ ObjectProvider template, AerospikeSettings settings) {
+ boolean indexesOnStartup = settings.getDataSettings().isCreateIndexesOnStartup();
log.debug("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup);
return new AerospikePersistenceEntityIndexCreator(aerospikeMappingContext, indexesOnStartup,
aerospikeIndexResolver, template);
@@ -78,11 +79,11 @@ public AerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCre
@Bean(name = "aerospikeIndexRefresher")
public IndexRefresher indexRefresher(IAerospikeClient aerospikeClient, IndexesCacheUpdater indexesCacheUpdater,
- ServerVersionSupport serverVersionSupport) {
+ ServerVersionSupport serverVersionSupport, AerospikeSettings settings) {
IndexRefresher refresher = new IndexRefresher(aerospikeClient, aerospikeClient.getInfoPolicyDefault(),
new InternalIndexOperations(new IndexInfoParser()), indexesCacheUpdater, serverVersionSupport);
refresher.refreshIndexes();
- int refreshFrequency = aerospikeDataSettings().getIndexCacheRefreshSeconds();
+ int refreshFrequency = settings.getDataSettings().getIndexCacheRefreshSeconds();
processCacheRefreshFrequency(refreshFrequency, refresher);
log.debug("AerospikeDataSettings.indexCacheRefreshSeconds: {}", refreshFrequency);
return refresher;
diff --git a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java
index 2a0a85df9..733312447 100644
--- a/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java
+++ b/src/main/java/org/springframework/data/aerospike/config/AbstractReactiveAerospikeDataConfiguration.java
@@ -40,7 +40,7 @@
import org.springframework.data.aerospike.server.version.ServerVersionSupport;
/**
- * Configuration with beans needed for reactive stuff
+ * Configuration with beans needed for reactive flow
*
* @author Igor Ermolenko
*/
@@ -55,22 +55,24 @@ public ReactiveAerospikeTemplate reactiveAerospikeTemplate(MappingAerospikeConve
IAerospikeReactorClient aerospikeReactorClient,
ReactorQueryEngine reactorQueryEngine,
ReactorIndexRefresher reactorIndexRefresher,
- ServerVersionSupport serverVersionSupport) {
- return new ReactiveAerospikeTemplate(aerospikeReactorClient, nameSpace(), mappingAerospikeConverter,
- aerospikeMappingContext, aerospikeExceptionTranslator, reactorQueryEngine, reactorIndexRefresher,
- serverVersionSupport);
+ ServerVersionSupport serverVersionSupport,
+ AerospikeSettings settings) {
+ return new ReactiveAerospikeTemplate(aerospikeReactorClient, settings.getConnectionSettings().getNamespace(),
+ mappingAerospikeConverter, aerospikeMappingContext, aerospikeExceptionTranslator,
+ reactorQueryEngine, reactorIndexRefresher, serverVersionSupport);
}
@Bean(name = "reactiveAerospikeQueryEngine")
public ReactorQueryEngine reactorQueryEngine(IAerospikeReactorClient aerospikeReactorClient,
StatementBuilder statementBuilder,
- FilterExpressionsBuilder filterExpressionsBuilder) {
+ FilterExpressionsBuilder filterExpressionsBuilder,
+ AerospikeSettings settings) {
ReactorQueryEngine queryEngine = new ReactorQueryEngine(aerospikeReactorClient, statementBuilder,
filterExpressionsBuilder);
- boolean scansEnabled = aerospikeDataSettings().isScansEnabled();
+ boolean scansEnabled = settings.getDataSettings().isScansEnabled();
queryEngine.setScansEnabled(scansEnabled);
log.debug("AerospikeDataSettings.scansEnabled: {}", scansEnabled);
- long queryMaxRecords = aerospikeDataSettings().getQueryMaxRecords();
+ long queryMaxRecords = settings.getDataSettings().getQueryMaxRecords();
log.debug("AerospikeDataSettings.queryMaxRecords: {}", queryMaxRecords);
queryEngine.setQueryMaxRecords(queryMaxRecords);
return queryEngine;
@@ -106,8 +108,8 @@ protected ClientPolicy getClientPolicy() {
public ReactiveAerospikePersistenceEntityIndexCreator aerospikePersistenceEntityIndexCreator(
ObjectProvider aerospikeMappingContext,
AerospikeIndexResolver aerospikeIndexResolver,
- ObjectProvider template) {
- boolean indexesOnStartup = aerospikeDataSettings().isCreateIndexesOnStartup();
+ ObjectProvider template, AerospikeSettings settings) {
+ boolean indexesOnStartup = settings.getDataSettings().isCreateIndexesOnStartup();
log.debug("AerospikeDataSettings.indexesOnStartup: {}", indexesOnStartup);
return new ReactiveAerospikePersistenceEntityIndexCreator(aerospikeMappingContext,
indexesOnStartup, aerospikeIndexResolver, template);
diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeConnectionSettings.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeConnectionSettings.java
new file mode 100644
index 000000000..13b4d675b
--- /dev/null
+++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeConnectionSettings.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.data.aerospike.config;
+
+import com.aerospike.client.Host;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class AerospikeConnectionSettings {
+
+ // String of hosts separated by ',' in form of hostname1[:tlsName1]:port1,...
+ // An IP address must be given in one of the following formats:
+ // IPv4: xxx.xxx.xxx.xxx
+ // IPv6: [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
+ // IPv6: [xxxx::xxxx]
+ // IPv6 addresses must be enclosed by brackets. tlsName is optional.
+ String hosts;
+ // Namespace
+ String namespace;
+ // Storing hosts
+ Host[] hostsArray;
+}
diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java
index c2709a1ca..6a89cded1 100644
--- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java
+++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataConfigurationSupport.java
@@ -21,6 +21,7 @@
import com.aerospike.client.policy.ClientPolicy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
@@ -71,9 +72,10 @@ public IndexesCacheHolder indexCache() {
@Bean(name = "mappingAerospikeConverter")
public MappingAerospikeConverter mappingAerospikeConverter(AerospikeMappingContext aerospikeMappingContext,
AerospikeTypeAliasAccessor aerospikeTypeAliasAccessor,
- AerospikeCustomConversions customConversions) {
+ AerospikeCustomConversions customConversions,
+ AerospikeSettings settings) {
return new MappingAerospikeConverter(aerospikeMappingContext, customConversions, aerospikeTypeAliasAccessor,
- aerospikeDataSettings());
+ settings.getDataSettings());
}
@Bean(name = "aerospikeTypeAliasAccessor")
@@ -105,9 +107,12 @@ public AerospikeExceptionTranslator aerospikeExceptionTranslator() {
}
@Bean(name = "aerospikeClient", destroyMethod = "close")
- public AerospikeClient aerospikeClient() {
- Collection hosts = getHosts();
- return new AerospikeClient(getClientPolicy(), hosts.toArray(new Host[0]));
+ public AerospikeClient aerospikeClient(AerospikeSettings settings) {
+ return new AerospikeClient(getClientPolicy(), settings.getConnectionSettings().getHostsArray());
+ }
+
+ protected int getDefaultPort() {
+ return 3000;
}
@Bean(name = "filterExpressionsBuilder")
@@ -122,9 +127,9 @@ public AerospikeIndexResolver aerospikeIndexResolver() {
}
@Bean(name = "aerospikeServerVersionSupport")
- public ServerVersionSupport serverVersionSupport(IAerospikeClient aerospikeClient) {
+ public ServerVersionSupport serverVersionSupport(IAerospikeClient aerospikeClient, AerospikeSettings settings) {
ServerVersionSupport serverVersionSupport = new ServerVersionSupport(aerospikeClient);
- int serverVersionRefreshFrequency = aerospikeDataSettings().getServerVersionRefreshSeconds();
+ int serverVersionRefreshFrequency = settings.getDataSettings().getServerVersionRefreshSeconds();
processServerVersionRefreshFrequency(serverVersionRefreshFrequency, serverVersionSupport);
return serverVersionSupport;
}
@@ -168,20 +173,33 @@ protected FieldNamingStrategy fieldNamingStrategy() {
return PropertyNameFieldNamingStrategy.INSTANCE;
}
- protected abstract Collection getHosts();
-
- protected abstract String nameSpace();
+ /**
+ * Override this method to define the hosts to be used.
+ *
The return value of this method overrides the value of the 'hosts' parameter from application.properties.
+ *
+ * @return Collection of Host objects for Aerospike client to connect
+ */
+ protected Collection getHosts() {
+ return null;
+ }
- protected AerospikeDataSettings aerospikeDataSettings() {
- AerospikeDataSettings.AerospikeDataSettingsBuilder builder = AerospikeDataSettings.builder();
- configureDataSettings(builder);
- return builder.build();
+ /**
+ * Override this method to define the namespace to be used.
+ *
The return value of this method overrides the value of the 'namespace' parameter from application.properties.
+ *
+ * @return Collection of Host objects for Aerospike client to connect
+ */
+ protected String nameSpace() {
+ return null;
}
- protected void configureDataSettings(AerospikeDataSettings.AerospikeDataSettingsBuilder builder) {
- builder.scansEnabled(false);
- builder.sendKey(true);
- builder.createIndexesOnStartup(true);
+ /**
+ * Override this method to define data settings to be used.
+ *
+ *
The return value of this method overrides the values of 'spring-data-aerospike.data.*' parameters
+ * from application.properties.
+ */
+ protected void configureDataSettings(AerospikeDataSettings aerospikeDataSettings) {
}
/**
@@ -196,9 +214,44 @@ protected ClientPolicy getClientPolicy() {
ClientPolicy clientPolicy = new ClientPolicy();
clientPolicy.failIfNotConnected = true;
clientPolicy.timeout = 10_000;
- clientPolicy.writePolicyDefault.sendKey = aerospikeDataSettings().isSendKey();
- clientPolicy.readPolicyDefault.sendKey = aerospikeDataSettings().isSendKey();
- log.debug("AerospikeDataSettings.sendKey: {}", clientPolicy.writePolicyDefault.sendKey);
+ clientPolicy.readPolicyDefault.sendKey = true;
+ clientPolicy.writePolicyDefault.sendKey = true;
+ clientPolicy.batchPolicyDefault.sendKey = true;
return clientPolicy;
}
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring-data-aerospike.data")
+ public AerospikeDataSettings readAerospikeDataSettings() {
+ return new AerospikeDataSettings();
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring-data-aerospike.connection")
+ public AerospikeConnectionSettings readAerospikeSettings() {
+ return new AerospikeConnectionSettings();
+ }
+
+ @Bean
+ protected AerospikeSettings aerospikeSettings(AerospikeDataSettings dataSettings,
+ AerospikeConnectionSettings connectionSettings) {
+ // values set via configureDataSettings() have precedence over the parameters from application.properties
+ configureDataSettings(dataSettings);
+
+ // getHosts() return value has precedence over hosts parameter from application.properties
+ Collection hosts;
+ if ((hosts = getHosts()) != null) {
+ connectionSettings.setHostsArray(hosts.toArray(new Host[0]));
+ } else if (!StringUtils.hasText(connectionSettings.getHosts())) {
+ throw new IllegalStateException("No hosts found, please set hosts parameter in application.properties or " +
+ "override getHosts() method");
+ }
+ connectionSettings.setHostsArray(Host.parseHosts(connectionSettings.getHosts(), getDefaultPort()));
+
+ // nameSpace() return value has precedence over namespace parameter from application.properties
+ String namespace;
+ if ((namespace = nameSpace()) != null) connectionSettings.setNamespace(namespace);
+
+ return new AerospikeSettings(connectionSettings, dataSettings);
+ }
}
diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java
index 2fa76f6a7..7246a964e 100644
--- a/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java
+++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeDataSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 the original author or authors.
+ * Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,47 +15,26 @@
*/
package org.springframework.data.aerospike.config;
-import lombok.Builder;
-import lombok.Value;
+import lombok.Getter;
+import lombok.Setter;
-@Builder
-@Value
+@Setter
+@Getter
public class AerospikeDataSettings {
- @Builder.Default
// Enable scan operation
boolean scansEnabled = false;
- @Builder.Default
- // Send user defined key in addition to hash digest on both reads and writes
- boolean sendKey = true;
- @Builder.Default
// Create secondary indexes specified using `@Indexed` annotation on startup
boolean createIndexesOnStartup = true;
- @Builder.Default
// Automatically refresh indexes cache every seconds
int indexCacheRefreshSeconds = 3600;
- @Builder.Default
// Automatically refresh cached server version every seconds
int serverVersionRefreshSeconds = 3600;
- @Builder.Default
// Limit amount of results returned by server. Non-positive value means no limit
long queryMaxRecords = 10_000L;
- @Builder.Default
// Maximum batch size for batch write operations
int batchWriteSize = 100;
// Define how @Id fields (primary keys) and Map keys are stored: false - always as String,
// true - preserve original type if supported
- @Builder.Default
boolean keepOriginalKeyTypes = false;
-
- /*
- * (non-Javadoc)
- * Javadoc is not aware of the code modifications made by Lombok.
- * You can fix it with either delombok or by adding a static inner class inside the class that uses the @Builder
- * annotation,
- * it will satisfy javadoc and won't interfere with the @Builder annotation's normal behaviour.
- */
- public static class AerospikeDataSettingsBuilder {
-
- }
}
diff --git a/src/main/java/org/springframework/data/aerospike/config/AerospikeSettings.java b/src/main/java/org/springframework/data/aerospike/config/AerospikeSettings.java
new file mode 100644
index 000000000..1882f955b
--- /dev/null
+++ b/src/main/java/org/springframework/data/aerospike/config/AerospikeSettings.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.data.aerospike.config;
+
+import lombok.Data;
+
+/**
+ * Class that holds configuration settings
+ */
+@Data
+public class AerospikeSettings {
+
+ final AerospikeConnectionSettings connectionSettings;
+ final AerospikeDataSettings dataSettings;
+}
diff --git a/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java b/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java
index 8365f75ba..f50f67419 100644
--- a/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java
+++ b/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java
@@ -38,5 +38,5 @@ public interface AerospikeConverter extends AerospikeReader