IGNITE-16869 Remove outdated spring data extensions with upgrading spring-core dependency (#120)
diff --git a/modules/aws-ext/pom.xml b/modules/aws-ext/pom.xml
index e6452ff..d31563b 100644
--- a/modules/aws-ext/pom.xml
+++ b/modules/aws-ext/pom.xml
@@ -33,7 +33,6 @@
<url>https://ignite.apache.org</url>
<properties>
- <spring.version>5.3.8</spring.version>
<aws.sdk.version>1.11.75</aws.sdk.version>
<aws.encryption.sdk.version>1.3.2</aws.encryption.sdk.version>
<bouncycastle.version>1.69</bouncycastle.version>
@@ -172,7 +171,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
@@ -185,14 +184,14 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/modules/azure-ext/pom.xml b/modules/azure-ext/pom.xml
index a5318ac..5112e4f 100644
--- a/modules/azure-ext/pom.xml
+++ b/modules/azure-ext/pom.xml
@@ -32,7 +32,6 @@
<url>https://ignite.apache.org</url>
<properties>
- <spring.version>5.3.8</spring.version>
<netty.version>4.1.66.Final</netty.version>
</properties>
@@ -359,21 +358,21 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/modules/gce-ext/pom.xml b/modules/gce-ext/pom.xml
index 41e2ae4..5b03a0e 100644
--- a/modules/gce-ext/pom.xml
+++ b/modules/gce-ext/pom.xml
@@ -31,10 +31,6 @@
<version>1.0.0-SNAPSHOT</version>
<url>https://ignite.apache.org</url>
- <properties>
- <spring.version>5.3.8</spring.version>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.apache.ignite</groupId>
@@ -91,21 +87,21 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
diff --git a/modules/spring-boot-autoconfigure-ext/pom.xml b/modules/spring-boot-autoconfigure-ext/pom.xml
index 8ad0018..d0a56d4 100644
--- a/modules/spring-boot-autoconfigure-ext/pom.xml
+++ b/modules/spring-boot-autoconfigure-ext/pom.xml
@@ -58,22 +58,22 @@
<dependency>
<groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.2-ext</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
+ <artifactId>ignite-spring-data-ext</artifactId>
+ <version>${ignite-spring-data-ext.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.2.version}</version>
+ <version>${spring.data.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
- <version>${spring-5.2.version}</version>
+ <version>${spring.version}</version>
<optional>true</optional>
</dependency>
diff --git a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
index 8829d3a..e787a41 100644
--- a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
+++ b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
@@ -18,10 +18,10 @@
package org.apache.ignite.springframework.boot.autoconfigure;
import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
import org.apache.ignite.springframework.boot.autoconfigure.data.IgniteRepositoriesAutoConfigurationRegistrar;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
index 24b0992..d24b389 100644
--- a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
+++ b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
@@ -18,8 +18,8 @@
package org.apache.ignite.springframework.boot.autoconfigure.data;
import java.lang.annotation.Annotation;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
diff --git a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
index e1e86ca..66e71fb 100644
--- a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
+++ b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
@@ -17,7 +17,7 @@
package org.apache.ignite.springframework.boot.autoconfigure;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
import org.apache.ignite.springframework.boot.autoconfigure.misc.DefaultTestConfigutation;
import org.apache.ignite.springframework.boot.autoconfigure.misc.ObjectRepository;
import org.junit.jupiter.api.Test;
diff --git a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
index 0e68033..fcd6576 100644
--- a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
+++ b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
@@ -17,8 +17,8 @@
package org.apache.ignite.springframework.boot.autoconfigure.misc;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
/**
* Test repository.
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml b/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
index 4188bfd..0d338a4 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
@@ -59,22 +59,22 @@
<dependency>
<groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.2-ext</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
+ <artifactId>ignite-spring-data-ext</artifactId>
+ <version>${ignite-spring-data-ext.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.2.version}</version>
+ <version>${spring.data.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
- <version>${spring-5.2.version}</version>
+ <version>${spring.version}</version>
<optional>true</optional>
</dependency>
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
index 1f54feb..ac42fa0 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
@@ -18,10 +18,10 @@
package org.apache.ignite.springframework.boot.autoconfigure;
import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
import org.apache.ignite.springframework.boot.autoconfigure.data.IgniteRepositoriesAutoConfigurationRegistrar;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
index 24b0992..d24b389 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
@@ -18,8 +18,8 @@
package org.apache.ignite.springframework.boot.autoconfigure.data;
import java.lang.annotation.Annotation;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
index 1cb58cc..4fae8f2 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
@@ -21,7 +21,7 @@
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.ClientConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
import org.apache.ignite.springframework.boot.autoconfigure.misc.ObjectRepository;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
index 0e68033..fcd6576 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
@@ -17,8 +17,8 @@
package org.apache.ignite.springframework.boot.autoconfigure.misc;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
/**
* Test repository.
diff --git a/modules/spring-data-2.0-ext/README.txt b/modules/spring-data-2.0-ext/README.txt
deleted file mode 100644
index b3d117b..0000000
--- a/modules/spring-data-2.0-ext/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Apache Ignite Spring Module
----------------------------
-
-Apache Ignite Spring Data 2.0 extension provides an integration with Spring Data 2.0 framework.
-
-Main features:
-
-- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
-- Supports query tuning parameters in @Query annotation
-- Supports projections
-- Supports Page and Stream responses
-- Supports Sql Fields Query resultset transformation into the domain entity
-- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
-- Supports advanced parameter binding and SpEL expressions into SQL queries:
-- Template variables:
- - #entityName - the simple class name of the domain entity
-- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
-- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
-- Supports SpEL expressions into Text queries (TextQuery).
-
-Importing Spring Data 2.0 extension In Maven Project
-----------------------------------------
-
-If you are using Maven to manage dependencies of your project, you can add Spring Data 2.0 extension
-dependency like this (replace '${ignite-spring-data-2.0-ext.version}' with actual version of Ignite Spring Data 2.0
-extension you are interested in):
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
- http://maven.apache.org/xsd/maven-4.0.0.xsd">
- ...
- <dependencies>
- ...
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.0-ext</artifactId>
- <version>${ignite-spring-data-2.0-ext.version}</version>
- </dependency>
- ...
- </dependencies>
- ...
-</project>
diff --git a/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml b/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml
deleted file mode 100644
index 4f51c12..0000000
--- a/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- Ignite Spring configuration file to startup Ignite cache.
-
- This file demonstrates how to configure cache using Spring. Provided cache
- will be created on node startup.
-
- Use this configuration file when running Spring Data examples.
-
- When starting a standalone node, you need to execute the following command:
- {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-2.0/examples/config/example-spring-data.xml
-
- When starting Ignite from Java IDE, pass path to this file to Ignition:
- Ignition.start("modules/spring-data-2.0/examples/config/example-spring-data.xml");
--->
-<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">
- <!-- Imports default Ignite configuration -->
- <import resource="example-default.xml"/>
-
- <bean parent="ignite.cfg">
- <property name="igniteInstanceName" value="springDataNode" />
-
- <property name="cacheConfiguration">
- <list>
- <bean class="org.apache.ignite.configuration.CacheConfiguration">
- <!--
- Apache Ignite uses an IgniteRepository extension which inherits from Spring Data's CrudRepository.
- The SQL grid is also enabled to aceess Spring Data repository. The @RepositoryConfig annotation
- maps the PersonRepository to an Ignite's cache named "PersonCache".
- -->
- <property name="name" value="PersonCache"/>
- <property name="indexedTypes">
- <list>
- <value>java.lang.Long</value>
- <value>org.apache.ignite.springdata20.examples.model.Person</value>
- </list>
- </property>
- </bean>
- </list>
- </property>
- </bean>
-</beans>
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java
deleted file mode 100644
index e04a50a..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.configuration.ClientConnectorConfiguration.DFLT_PORT;
-
-/**
- * Example of Spring application configuration that represents beans required to configure Spring Data repository access
- * to an Ignite cluster through the thin client.
- *
- * Note that both Ignite thin client and Ignite node approaches of Ignite cluster access configuration uses the same API.
- * Ignite Spring Data integration automatically recognizes the type of provided bean and use the appropriate
- * cluster connection.
- *
- * @see SpringApplicationConfiguration
- */
-@Configuration
-@EnableIgniteRepositories
-public class IgniteClientSpringApplicationConfiguration {
- /**
- * Creates Apache Ignite thin client instance bean which will be used for accessing the Ignite cluster.
- * Note, that the name of the current bean must match value of {@link RepositoryConfig#igniteInstance}
- * property that {@link PersonRepository} is marked with. In this particular case, the default value of
- * {@link RepositoryConfig#igniteInstance} property is used.
- */
- @Bean
- public IgniteClient igniteInstance() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + DFLT_PORT));
- }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java
deleted file mode 100644
index 2e0a729..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.examples.model.Person;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-
-/**
- * Apache Ignite Spring Data repository backed by Ignite Person's cache.
- * </p>
- * To link the repository with an Ignite cache use {@link RepositoryConfig#cacheName()} annotation's parameter.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Long> {
- /**
- * Gets all the persons with the given name.
- * @param name Person name.
- * @return A list of Persons with the given first name.
- */
- public List<Person> findByFirstName(String name);
-
- /**
- * Returns top Person with the specified surname.
- * @param name Person surname.
- * @return Person that satisfy the query.
- */
- public Cache.Entry<Long, Person> findTopByLastNameLike(String name);
-
- /**
- * Getting ids of all the Person satisfying the custom query from {@link Query} annotation.
- *
- * @param orgId Query parameter.
- * @param pageable Pageable interface.
- * @return A list of Persons' ids.
- */
- @Query("SELECT id FROM Person WHERE orgId > ?")
- public List<Long> selectId(long orgId, Pageable pageable);
-}
-
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java
deleted file mode 100644
index 15ded04..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Every {@link IgniteRepository} is bound to a specific Apache Ignite that it communicates to in order to mutate and
- * read data via Spring Data API. To pass an instance of Apache Ignite cache to an {@link IgniteRepository} it's
- * required to initialize {@link IgniteRepositoryFactoryBean} with one of the following:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
- * <ul/>
- * In this example the first approach is utilized.
- */
-@Configuration
-@EnableIgniteRepositories
-public class SpringApplicationConfiguration {
- /**
- * Creating Apache Ignite instance bean. A bean will be passed to {@link IgniteRepositoryFactoryBean} to initialize
- * all Ignite based Spring Data repositories and connect to a cluster.
- */
- @Bean
- public Ignite igniteInstance() {
- return Ignition.start("modules/spring-data-2.0-ext/examples/config/example-spring-data.xml");
- }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java
deleted file mode 100644
index 325dd54..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.TreeMap;
-import javax.cache.Cache;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.examples.model.Person;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-
-/**
- * The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
- *
- * Additional cluster nodes can be started with special configuration file which
- * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data-2.0/examples/config/example-spring-data.xml'}.
- */
-public class SpringDataExample {
- /** Spring Application Context. */
- private static AnnotationConfigApplicationContext ctx;
-
- /** Ignite Spring Data repository. */
- private static PersonRepository repo;
-
- /**
- * Execute examples involving both approaches to configure Spring Data repository access to an Ignite cluster:
- * through Ignite thin client and through Ignite node.
- * @param args Command line arguments, none required.
- */
- public static void main(String[] args) {
- try (Ignite ignored = startIgniteNode()) {
- // Ignite node instance is used to configure access to the Ignite cluster.
- doSpringDataExample(SpringApplicationConfiguration.class);
-
- // Ignite thin client instance is used to configure access to the Ignite cluster.
- doSpringDataExample(IgniteClientSpringApplicationConfiguration.class);
- }
- }
-
- /** Starts an Ignite node that simulates an Ignite cluster to which Spring Data repository will perform access. */
- private static Ignite startIgniteNode() {
- IgniteConfiguration cfg = new IgniteConfiguration()
- .setPeerClassLoadingEnabled(true)
- .setCacheConfiguration(new CacheConfiguration<Long, Person>("PersonCache")
- .setIndexedTypes(Long.class, Person.class));
-
- return Ignition.start(cfg);
- }
-
- /**
- * Performs basic Spring Data repository operation.
- *
- * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
- */
- private static void doSpringDataExample(Class<?> springAppCfg) {
- igniteSpringDataInit(springAppCfg);
-
- populateRepository();
-
- findPersons();
-
- queryRepository();
-
- System.out.println("\n>>> Cleaning out the repository...");
-
- repo.deleteAll();
-
- System.out.println("\n>>> Repository size: " + repo.count());
-
- // Destroying the context.
- ctx.destroy();
- }
-
- /**
- * Initializes Spring Data and Ignite repositories.
- *
- * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
- */
- private static void igniteSpringDataInit(Class<?> springAppCfg) {
- ctx = new AnnotationConfigApplicationContext();
-
- // Explicitly registering Spring configuration.
- ctx.register(springAppCfg);
-
- ctx.refresh();
-
- // Getting a reference to PersonRepository.
- repo = ctx.getBean(PersonRepository.class);
- }
-
- /**
- * Fills the repository in with sample data.
- */
- private static void populateRepository() {
- TreeMap<Long, Person> persons = new TreeMap<>();
-
- persons.put(1L, new Person(1L, 2000L, "John", "Smith", 15000, "Worked for Apple"));
- persons.put(2L, new Person(2L, 2000L, "Brad", "Pitt", 16000, "Worked for Oracle"));
- persons.put(3L, new Person(3L, 1000L, "Mark", "Tomson", 10000, "Worked for Sun"));
- persons.put(4L, new Person(4L, 2000L, "Erick", "Smith", 13000, "Worked for Apple"));
- persons.put(5L, new Person(5L, 1000L, "John", "Rozenberg", 25000, "Worked for RedHat"));
- persons.put(6L, new Person(6L, 2000L, "Denis", "Won", 35000, "Worked for CBS"));
- persons.put(7L, new Person(7L, 1000L, "Abdula", "Adis", 45000, "Worked for NBC"));
- persons.put(8L, new Person(8L, 2000L, "Roman", "Ive", 15000, "Worked for Sun"));
-
- // Adding data into the repository.
- repo.save(persons);
-
- System.out.println("\n>>> Added " + repo.count() + " Persons into the repository.");
- }
-
- /**
- * Gets a list of Persons using standard read operations.
- */
- private static void findPersons() {
- // Getting Person with specific ID.
- Person person = repo.findById(2L).orElse(null);
-
- System.out.println("\n>>> Found Person [id=" + 2L + ", val=" + person + "]");
-
- // Getting a list of Persons.
-
- ArrayList<Long> ids = new ArrayList<>();
-
- for (long i = 0; i < 5; i++)
- ids.add(i);
-
- Iterator<Person> persons = repo.findAllById(ids).iterator();
-
- System.out.println("\n>>> Persons list for specific ids: ");
-
- while (persons.hasNext())
- System.out.println(" >>> " + persons.next());
- }
-
- /**
- * Execute advanced queries over the repository.
- */
- private static void queryRepository() {
- System.out.println("\n>>> Persons with name 'John':");
-
- List<Person> persons = repo.findByFirstName("John");
-
- for (Person person: persons)
- System.out.println(" >>> " + person);
-
-
- Cache.Entry<Long, Person> topPerson = repo.findTopByLastNameLike("Smith");
-
- System.out.println("\n>>> Top Person with surname 'Smith': " + topPerson.getValue());
-
-
- List<Long> ids = repo.selectId(1000L, new PageRequest(0, 4));
-
- System.out.println("\n>>> Persons working for organization with ID > 1000: ");
-
- for (Long id: ids)
- System.out.println(" >>> [id=" + id + "]");
- }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java
deleted file mode 100644
index e7e6348..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinaryReader;
-import org.apache.ignite.binary.BinaryWriter;
-import org.apache.ignite.binary.Binarylizable;
-
-/**
- * Employee address.
- * <p>
- * This class implements {@link Binarylizable} only for example purposes,
- * in order to show how to customize serialization and deserialization of
- * binary objects.
- */
-public class Address implements Binarylizable {
- /** Street. */
- private String street;
-
- /** ZIP code. */
- private int zip;
-
- /**
- * Required for binary deserialization.
- */
- public Address() {
- // No-op.
- }
-
- /**
- * @param street Street.
- * @param zip ZIP code.
- */
- public Address(String street, int zip) {
- this.street = street;
- this.zip = zip;
- }
-
- /** {@inheritDoc} */
- @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
- writer.writeString("street", street);
- writer.writeInt("zip", zip);
- }
-
- /** {@inheritDoc} */
- @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
- street = reader.readString("street");
- zip = reader.readInt("zip");
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Address [street=" + street +
- ", zip=" + zip + ']';
- }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java
deleted file mode 100644
index 7996793..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-import java.util.Collection;
-
-/**
- * This class represents employee object.
- */
-public class Employee {
- /** Name. */
- private String name;
-
- /** Salary. */
- private long salary;
-
- /** Address. */
- private Address addr;
-
- /** Departments. */
- private Collection<String> departments;
-
- /**
- * Required for binary deserialization.
- */
- public Employee() {
- // No-op.
- }
-
- /**
- * @param name Name.
- * @param salary Salary.
- * @param addr Address.
- * @param departments Departments.
- */
- public Employee(String name, long salary,Address addr, Collection<String> departments) {
- this.name = name;
- this.salary = salary;
- this.addr = addr;
- this.departments = departments;
- }
-
- /**
- * @return Name.
- */
- public String name() {
- return name;
- }
-
- /**
- * @return Salary.
- */
- public long salary() {
- return salary;
- }
-
- /**
- * @return Address.
- */
- public Address address() {
- return addr;
- }
-
- /**
- * @return Departments.
- */
- public Collection<String> departments() {
- return departments;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Employee [name=" + name +
- ", salary=" + salary +
- ", address=" + addr +
- ", departments=" + departments + ']';
- }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java
deleted file mode 100644
index 7bcb0c2..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-/**
- * Organization type enum.
- */
-public enum OrganizationType {
- /** Non-profit organization. */
- NON_PROFIT,
-
- /** Private organization. */
- PRIVATE,
-
- /** Government organization. */
- GOVERNMENT
-}
diff --git a/modules/spring-data-2.0-ext/licenses/apache-2.0.txt b/modules/spring-data-2.0-ext/licenses/apache-2.0.txt
deleted file mode 100644
index d645695..0000000
--- a/modules/spring-data-2.0-ext/licenses/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml b/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml
deleted file mode 100755
index 3061bd4..0000000
--- a/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
- "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-<!--
- Log4j configuration.
--->
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
- <!--
- Logs System.out messages to console.
- -->
- <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
- <!-- Log to STDOUT. -->
- <param name="Target" value="System.out"/>
-
- <!-- Log from DEBUG and higher. -->
- <param name="Threshold" value="DEBUG"/>
-
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
-
- <!-- Do not log beyond INFO level. -->
- <filter class="org.apache.log4j.varia.LevelRangeFilter">
- <param name="levelMin" value="DEBUG"/>
- <param name="levelMax" value="INFO"/>
- </filter>
- </appender>
-
- <!--
- Logs all System.err messages to console.
- -->
- <appender name="CONSOLE_ERR" class="org.apache.log4j.ConsoleAppender">
- <!-- Log to STDERR. -->
- <param name="Target" value="System.err"/>
-
- <!-- Log from WARN and higher. -->
- <param name="Threshold" value="WARN"/>
-
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
- </appender>
-
- <!--
- Logs all output to specified file.
- -->
- <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
- <param name="Threshold" value="DEBUG"/>
- <param name="File" value="ignite/work/log/ignite.log"/>
- <param name="Append" value="true"/>
- <param name="MaxFileSize" value="10MB"/>
- <param name="MaxBackupIndex" value="10"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
- </appender>
-
- <!-- Disable all open source debugging. -->
- <category name="org">
- <level value="INFO"/>
- </category>
-
- <category name="org.eclipse.jetty">
- <level value="INFO"/>
- </category>
-
- <!-- Default settings. -->
- <root>
- <!-- Print at info by default. -->
- <level value="INFO"/>
-
- <!-- Append to file and console. -->
- <appender-ref ref="FILE"/>
- <appender-ref ref="CONSOLE"/>
- <appender-ref ref="CONSOLE_ERR"/>
- </root>
-</log4j:configuration>
diff --git a/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties b/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties
deleted file mode 100644
index 0faf5b8..0000000
--- a/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Local address to bind to.
-local.ip=127.0.0.1
-
-# TCP communication port
-comm.tcp.port=30010
diff --git a/modules/spring-data-2.0-ext/pom.xml b/modules/spring-data-2.0-ext/pom.xml
deleted file mode 100644
index d2d3f5b..0000000
--- a/modules/spring-data-2.0-ext/pom.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-extensions-parent</artifactId>
- <version>1</version>
- <relativePath>../../parent</relativePath>
- </parent>
-
- <artifactId>ignite-spring-data-2.0-ext</artifactId>
- <version>${ignite-spring-data-2.0-ext.version}</version>
- <url>http://ignite.apache.org</url>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-indexing</artifactId>
- <version>${ignite.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-commons</artifactId>
- <version>${ignite-spring-data-commons.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring-5.0.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring-5.0.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.0.version}</version>
- <scope>provided</scope>
- <!-- Exclude slf4j logging in favor of log4j -->
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>${commons.lang.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-log4j</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-tools</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java
deleted file mode 100644
index 8ba8de6..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository;
-
-import java.io.Serializable;
-import java.util.Map;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
- /**
- * Returns the Ignite instance bound to the repository
- *
- * @return the Ignite instance bound to the repository
- */
- public Ignite ignite();
-
- /**
- * Returns the Ignite Cache bound to the repository
- *
- * @return the Ignite Cache bound to the repository
- */
- public IgniteCache<K, V> cache();
-
- /**
- * Saves a given entity using provided key.
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Entity type.
- * @param key Entity's key.
- * @param entity Entity to save.
- * @return Saved entity.
- */
- public <S extends V> S save(K key, S entity);
-
- /**
- * Saves all given keys and entities combinations.
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Type of entities.
- * @param entities Map of key-entities pairs to save.
- * @return Saved entities.
- */
- public <S extends V> Iterable<S> save(Map<K, S> entities);
-
- /**
- * Saves a given entity using provided key with expiry policy
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Entity type.
- * @param key Entity's key.
- * @param entity Entity to save.
- * @param expiryPlc ExpiryPolicy to apply, if not null.
- * @return Saved entity.
- */
- public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
-
- /**
- * Saves all given keys and entities combinations with expiry policy
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Type of entities.
- * @param entities Map of key-entities pairs to save.
- * @param expiryPlc ExpiryPolicy to apply, if not null.
- * @return Saved entities.
- */
- public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
-
- /**
- * Deletes all the entities for the provided ids.
- *
- * @param ids List of ids to delete.
- */
- public void deleteAllById(Iterable<K> ids);
-
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java
deleted file mode 100644
index ed422a9..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-/**
- * Runtime Dynamic query configuration.
- * <p>
- * Can be used as special repository method parameter to provide at runtime:
- * <ol>
- * <li>Dynamic query string (requires {@link Query#dynamicQuery()} == true)
- * <li>Ignite query tuning*
- * </ol>
- * <p>
- * * Please, note that {@link Query} annotation parameters will be ignored in favor of those defined in
- * {@link DynamicQueryConfig} parameter if present.
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public class DynamicQueryConfig {
- /** */
- private String value = "";
-
- /** */
- private boolean textQuery;
-
- /** */
- private boolean forceFieldsQry;
-
- /** */
- private boolean collocated;
-
- /** */
- private int timeout;
-
- /** */
- private boolean enforceJoinOrder;
-
- /** */
- private boolean distributedJoins;
-
- /** */
- private boolean lazy;
-
- /** */
- private boolean local;
-
- /** */
- private int[] parts;
-
- /** */
- private int limit;
-
- /**
- * From Query annotation.
- *
- * @param queryConfiguration the query configuration
- * @return the dynamic query config
- */
- public static DynamicQueryConfig fromQueryAnnotation(Query queryConfiguration) {
- DynamicQueryConfig config = new DynamicQueryConfig();
- if (queryConfiguration != null) {
- config.value = queryConfiguration.value();
- config.collocated = queryConfiguration.collocated();
- config.timeout = queryConfiguration.timeout();
- config.enforceJoinOrder = queryConfiguration.enforceJoinOrder();
- config.distributedJoins = queryConfiguration.distributedJoins();
- config.lazy = queryConfiguration.lazy();
- config.parts = queryConfiguration.parts();
- config.local = queryConfiguration.local();
- config.limit = queryConfiguration.limit();
- }
- return config;
- }
-
- /**
- * Query text string.
- *
- * @return the string
- */
- public String value() {
- return value;
- }
-
- /**
- * Whether must use TextQuery search.
- *
- * @return the boolean
- */
- public boolean textQuery() {
- return textQuery;
- }
-
- /**
- * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
- * statements or to not return hidden fields on SELECT * statements.
- *
- * @return the boolean
- */
- public boolean forceFieldsQuery() {
- return forceFieldsQry;
- }
-
- /**
- * Sets flag defining if this query is collocated.
- * <p>
- * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
- * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
- * of your query selection are collocated together on the same node and you group by collocated key (primary or
- * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
- * nodes.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- *
- * @return the boolean
- */
- public boolean collocated() {
- return collocated;
- }
-
- /**
- * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
- * timeout is exceeded. Zero value disables timeout
- *
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- *
- * @return the int
- */
- public int timeout() {
- return timeout;
- }
-
- /**
- * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
- * tables in join. By default is {@code false}.
- * <p>
- * It is not recommended to enable this property until you are sure that your indexes and the query itself are
- * correct and tuned as much as possible but query optimizer still produces wrong join order.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- *
- * @return the boolean
- */
- public boolean enforceJoinOrder() {
- return enforceJoinOrder;
- }
-
- /**
- * Specify if distributed joins are enabled for this query.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- *
- * @return the boolean
- */
- public boolean distributedJoins() {
- return distributedJoins;
- }
-
- /**
- * Sets lazy query execution flag.
- * <p>
- * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
- * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
- * increasing concurrency.
- * <p>
- * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
- * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
- * consumption at the cost of moderate performance hit.
- * <p>
- * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
- * <p>
- * Only applicable to SqlFieldsQuery
- *
- * @return the boolean
- */
- public boolean lazy() {
- return lazy;
- }
-
- /**
- * Sets whether this query should be executed on local node only.
- *
- * @return the boolean
- */
- public boolean local() {
- return local;
- }
-
- /**
- * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
- * partitions.
- * <p>
- * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- *
- * @return the int [ ]
- */
- public int[] parts() {
- return parts;
- }
-
- /**
- * Gets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
- *
- * @return Limit value.
- */
- public int limit() {
- return limit;
- }
-
- /**
- * Sets value.
- *
- * @param value the value
- * @return this for chaining
- */
- public DynamicQueryConfig setValue(String value) {
- this.value = value;
- return this;
- }
-
- /**
- * Sets text query.
- *
- * @param textQuery the text query
- * @return this for chaining
- */
- public DynamicQueryConfig setTextQuery(boolean textQuery) {
- this.textQuery = textQuery;
- return this;
- }
-
- /**
- * Sets force fields query.
- *
- * @param forceFieldsQuery the force fields query
- * @return this for chaining
- */
- public DynamicQueryConfig setForceFieldsQuery(boolean forceFieldsQuery) {
- forceFieldsQry = forceFieldsQuery;
- return this;
- }
-
- /**
- * Sets collocated.
- *
- * @param collocated the collocated
- * @return this for chaining
- */
- public DynamicQueryConfig setCollocated(boolean collocated) {
- this.collocated = collocated;
- return this;
- }
-
- /**
- * Sets timeout.
- *
- * @param timeout the timeout
- * @return this for chaining
- */
- public DynamicQueryConfig setTimeout(int timeout) {
- this.timeout = timeout;
- return this;
- }
-
- /**
- * Sets enforce join order.
- *
- * @param enforceJoinOrder the enforce join order
- * @return this for chaining
- */
- public DynamicQueryConfig setEnforceJoinOrder(boolean enforceJoinOrder) {
- this.enforceJoinOrder = enforceJoinOrder;
- return this;
- }
-
- /**
- * Sets distributed joins.
- *
- * @param distributedJoins the distributed joins
- * @return this for chaining
- */
- public DynamicQueryConfig setDistributedJoins(boolean distributedJoins) {
- this.distributedJoins = distributedJoins;
- return this;
- }
-
- /**
- * Sets lazy.
- *
- * @param lazy the lazy
- * @return this for chaining
- */
- public DynamicQueryConfig setLazy(boolean lazy) {
- this.lazy = lazy;
- return this;
- }
-
- /**
- * Sets local.
- *
- * @param local the local
- * @return this for chaining
- */
- public DynamicQueryConfig setLocal(boolean local) {
- this.local = local;
- return this;
- }
-
- /**
- * Sets parts.
- *
- * @param parts the parts
- * @return this for chaining
- */
- public DynamicQueryConfig setParts(int[] parts) {
- this.parts = parts;
- return this;
- }
-
- /**
- * Sets limit to response records count for TextQuery.
- *
- * @param limit If 0 or less, considered to be no limit.
- * @return {@code this} For chaining.
- */
- public DynamicQueryConfig setLimit(int limit) {
- this.limit = limit;
- return this;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java
deleted file mode 100644
index 1bab4ca..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryImpl;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Import;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-
-/**
- * Annotation to activate Apache Ignite repositories. If no base package is configured through either {@link #value()},
- * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-@Import(IgniteRepositoriesRegistar.class)
-public @interface EnableIgniteRepositories {
- /**
- * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
- * {@code @EnableIgniteRepositories("org.my.pkg")} instead of
- * {@code @EnableIgniteRepositories(basePackages="org.my.pkg")}.
- */
- String[] value() default {};
-
- /**
- * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with)
- * this attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
- */
- String[] basePackages() default {};
-
- /**
- * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components.
- * The package of each class specified will be scanned. Consider creating a special no-op marker class or interface
- * in each package that serves no purpose other than being referenced by this attribute.
- */
- Class<?>[] basePackageClasses() default {};
-
- /**
- * Specifies which types are not eligible for component scanning.
- */
- Filter[] excludeFilters() default {};
-
- /**
- * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
- * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or
- * filters.
- */
- Filter[] includeFilters() default {};
-
- /**
- * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
- * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
- * for {@code PersonRepositoryImpl}.
- *
- * @return Postfix to be used when looking up custom repository implementations.
- */
- String repositoryImplementationPostfix() default "Impl";
-
- /**
- * Configures the location of where to find the Spring Data named queries properties file.
- *
- * @return Location of where to find the Spring Data named queries properties file.
- */
- String namedQueriesLocation() default "";
-
- /**
- * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
- * {@link Key#CREATE_IF_NOT_FOUND}.
- *
- * @return Key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods.
- */
- Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
-
- /**
- * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
- * IgniteRepositoryFactoryBean}.
- *
- * @return {@link FactoryBean} class to be used for each repository instance.
- */
- Class<?> repositoryFactoryBeanClass() default IgniteRepositoryFactoryBean.class;
-
- /**
- * Configure the repository base class to be used to create repository proxies for this particular configuration.
- *
- * @return Repository base class to be used to create repository proxies for this particular configuration.
- */
- Class<?> repositoryBaseClass() default IgniteRepositoryImpl.class;
-
- /**
- * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
- * repositories infrastructure.
- */
- boolean considerNestedRepositories() default false;
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java
deleted file mode 100644
index 83ff7ff..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Annotation;
-import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryBeanDefinitionRegistrarSupport}.
- */
-public class IgniteRepositoriesRegistar extends RepositoryBeanDefinitionRegistrarSupport {
- /** {@inheritDoc} */
- @Override protected Class<? extends Annotation> getAnnotation() {
- return EnableIgniteRepositories.class;
- }
-
- /** {@inheritDoc} */
- @Override protected RepositoryConfigurationExtension getExtension() {
- return new IgniteRepositoryConfigurationExtension();
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java
deleted file mode 100644
index de8cf0b..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.util.Collection;
-import java.util.Collections;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.support.IgniteProxyFactory;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationSource;
-
-import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
- */
-public class IgniteRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
- /** Name of the auto-registered Ignite proxy factory bean. */
- private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
-
- /** Name of the auto-registered Ignite proxy bean prototype. */
- private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
-
- /** {@inheritDoc} */
- @Override public String getModuleName() {
- return "Apache Ignite";
- }
-
- /** {@inheritDoc} */
- @Override protected String getModulePrefix() {
- return "ignite";
- }
-
- /** {@inheritDoc} */
- @Override public String getRepositoryFactoryBeanClassName() {
- return IgniteRepositoryFactoryBean.class.getName();
- }
-
- /** {@inheritDoc} */
- @Override protected Collection<Class<?>> getIdentifyingTypes() {
- return Collections.singleton(IgniteRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
- registerIfNotAlreadyRegistered(
- BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
- registry,
- IGNITE_PROXY_FACTORY_BEAN_NAME,
- cfg);
-
- registerIfNotAlreadyRegistered(
- BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
- .setScope(SCOPE_PROTOTYPE)
- .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
- .getBeanDefinition(),
- registry,
- IGNITE_PROXY_BEAN_NAME,
- cfg);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java
deleted file mode 100644
index 2db7c25..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-
-/**
- * Annotation to provide a user defined query for a method.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Query {
- /**
- * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
- * (only if textQuery = false (default))
- */
- String value() default "";
-
- /**
- * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
- * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
- *
- * @see RepositoryConfig#igniteInstance()
- */
- boolean textQuery() default false;
-
- /**
- * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
- * statements or to not return hidden fields on SELECT * statements.
- */
- boolean forceFieldsQuery() default false;
-
- /**
- * Sets flag defining if this query is collocated.
- * <p>
- * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
- * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
- * of your query selection are collocated together on the same node and you group by collocated key (primary or
- * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
- * nodes.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean collocated() default false;
-
- /**
- * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
- * timeout is exceeded. Zero value disables timeout
- *
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- int timeout() default 0;
-
- /**
- * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
- * tables in join. By default is {@code false}.
- * <p>
- * It is not recommended to enable this property until you are sure that your indexes and the query itself are
- * correct and tuned as much as possible but query optimizer still produces wrong join order.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean enforceJoinOrder() default false;
-
- /**
- * Specify if distributed joins are enabled for this query.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- boolean distributedJoins() default false;
-
- /**
- * Sets lazy query execution flag.
- * <p>
- * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
- * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
- * increasing concurrency.
- * <p>
- * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
- * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
- * consumption at the cost of moderate performance hit.
- * <p>
- * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean lazy() default false;
-
- /**
- * Sets whether this query should be executed on local node only.
- */
- boolean local() default false;
-
- /**
- * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
- * partitions.
- * <p>
- * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- int[] parts() default {};
-
- /**
- * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
- * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
- * <p>
- * Please, note that {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
- * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
- */
- boolean dynamicQuery() default false;
-
- /**
- * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
- */
- int limit() default 0;
-
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java
deleted file mode 100644
index a156d81..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-
-/**
- * The annotation can be used to pass Ignite specific parameters to a bound repository.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-public @interface RepositoryConfig {
- /**
- * Cache name string.
- *
- * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
- */
- String cacheName() default "";
-
- /**
- * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
- * Ignite cluster.
- */
- String igniteInstance() default "igniteInstance";
-
- /**
- * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
- * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
- */
- String igniteCfg() default "igniteCfg";
-
- /**
- * Ignite spring cfg path string. Default "igniteSpringCfgPath".
- *
- * @return A path to Ignite's Spring XML configuration spring bean name
- */
- String igniteSpringCfgPath() default "igniteSpringCfgPath";
-
- /**
- * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
- * <p>
- * Tells to Ignite Repository factory wether cache should be auto created if not exists.
- *
- * @return the boolean
- */
- boolean autoCreateCache() default false;
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java
deleted file mode 100644
index 1c7b2f9..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes Spring Data integration related configuration files.
- */
-package org.apache.ignite.springdata20.repository.config;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java
deleted file mode 100644
index 9df5513..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains Apache Ignite Spring Data integration.
- */
-package org.apache.ignite.springdata20.repository;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java
deleted file mode 100644
index 4714f38..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.util.Collections;
-import java.util.List;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * NULL-Object pattern implementation for {@link DeclaredQuery}.
- *
- * @author Jens Schauder
- */
-class EmptyDeclaredQuery implements DeclaredQuery {
- /**
- * An implementation implementing the NULL-Object pattern for situations where there is no query.
- */
- static final DeclaredQuery EMPTY_QUERY = new EmptyDeclaredQuery();
-
- /** {@inheritDoc} */
- @Override public boolean hasNamedParameter() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public String getQueryString() {
- return "";
- }
-
- /** {@inheritDoc} */
- @Override public String getAlias() {
- return null;
- }
-
- /** {@inheritDoc} */
- @Override public boolean hasConstructorExpression() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isDefaultProjection() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public List<StringQuery.ParameterBinding> getParameterBindings() {
- return Collections.emptyList();
- }
-
- /** {@inheritDoc} */
- @Override public DeclaredQuery deriveCountQuery(@Nullable String cntQry, @Nullable String cntQryProjection) {
- Assert.hasText(cntQry, "CountQuery must not be empty!");
- return DeclaredQuery.of(cntQry);
- }
-
- /** {@inheritDoc} */
- @Override public boolean usesJdbcStyleParameters() {
- return false;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java
deleted file mode 100644
index b1115ae..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.util.regex.Pattern;
-import org.springframework.data.repository.core.EntityMetadata;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.expression.Expression;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-import org.springframework.util.Assert;
-
-/**
- * Extension of {@link StringQuery} that evaluates the given query string as a SpEL template-expression.
- * <p>
- * Currently the following template variables are available:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the given entity</li>
- * <ol>
- *
- * @author Thomas Darimont
- * @author Oliver Gierke
- * @author Tom Hombergs
- */
-class ExpressionBasedStringQuery extends StringQuery {
- /**
- * Expression parameter.
- */
- private static final String EXPRESSION_PARAMETER = "?#{";
-
- /**
- * Quoted expression parameter.
- */
- private static final String QUOTED_EXPRESSION_PARAMETER = "?__HASH__{";
-
- /**
- * Expression parameter quoting.
- */
- private static final Pattern EXPRESSION_PARAMETER_QUOTING = Pattern.compile(Pattern.quote(EXPRESSION_PARAMETER));
-
- /**
- * Expression parameter unquoting.
- */
- private static final Pattern EXPRESSION_PARAMETER_UNQUOTING = Pattern.compile(
- Pattern.quote(QUOTED_EXPRESSION_PARAMETER));
-
- /**
- * Entity name.
- */
- private static final String ENTITY_NAME = "entityName";
-
- /**
- * Entity name variable.
- */
- private static final String ENTITY_NAME_VARIABLE = "#" + ENTITY_NAME;
-
- /**
- * Entity name variable expression.
- */
- private static final String ENTITY_NAME_VARIABLE_EXPRESSION = "#{" + ENTITY_NAME_VARIABLE + "}";
-
- /**
- * Creates a new instance for the given query and {@link EntityMetadata}.
- *
- * @param qry must not be {@literal null} or empty.
- * @param metadata must not be {@literal null}.
- * @param parser must not be {@literal null}.
- */
- public ExpressionBasedStringQuery(String qry, RepositoryMetadata metadata, SpelExpressionParser parser) {
- super(renderQueryIfExpressionOrReturnQuery(qry, metadata, parser));
- }
-
- /**
- * Creates an instance from a given {@link DeclaredQuery}.
- *
- * @param qry the original query. Must not be {@literal null}.
- * @param metadata the {@link RepositoryMetadata} for the given entity. Must not be {@literal null}.
- * @param parser Parser for resolving SpEL expressions. Must not be {@literal null}.
- * @return A query supporting SpEL expressions.
- */
- static ExpressionBasedStringQuery from(DeclaredQuery qry,
- RepositoryMetadata metadata,
- SpelExpressionParser parser) {
- return new ExpressionBasedStringQuery(qry.getQueryString(), metadata, parser);
- }
-
- /**
- * @param qry, the query expression potentially containing a SpEL expression. Must not be {@literal null}.}
- * @param metadata the {@link RepositoryMetadata} for the given entity. Must not be {@literal null}.
- * @param parser Must not be {@literal null}.
- * @return rendered query
- */
- private static String renderQueryIfExpressionOrReturnQuery(String qry,
- RepositoryMetadata metadata,
- SpelExpressionParser parser) {
-
- Assert.notNull(qry, "query must not be null!");
- Assert.notNull(metadata, "metadata must not be null!");
- Assert.notNull(parser, "parser must not be null!");
-
- if (!containsExpression(qry))
- return qry;
-
- StandardEvaluationContext evalCtx = new StandardEvaluationContext();
- evalCtx.setVariable(ENTITY_NAME, metadata.getDomainType().getSimpleName());
-
- qry = potentiallyQuoteExpressionsParameter(qry);
-
- Expression expr = parser.parseExpression(qry, ParserContext.TEMPLATE_EXPRESSION);
-
- String result = expr.getValue(evalCtx, String.class);
-
- if (result == null)
- return qry;
-
- return potentiallyUnquoteParameterExpressions(result);
- }
-
- /**
- * @param result Result.
- */
- private static String potentiallyUnquoteParameterExpressions(String result) {
- return EXPRESSION_PARAMETER_UNQUOTING.matcher(result).replaceAll(EXPRESSION_PARAMETER);
- }
-
- /**
- * @param qry Query.
- */
- private static String potentiallyQuoteExpressionsParameter(String qry) {
- return EXPRESSION_PARAMETER_QUOTING.matcher(qry).replaceAll(QUOTED_EXPRESSION_PARAMETER);
- }
-
- /**
- * @param qry Query.
- */
- private static boolean containsExpression(String qry) {
- return qry.contains(ENTITY_NAME_VARIABLE_EXPRESSION);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java
deleted file mode 100644
index f8e6d48..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import org.apache.ignite.internal.util.typedef.internal.S;
-
-/**
- * Ignite query helper class. For internal use only.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteQuery {
- /** */
- enum Option {
- /** Query will be used with Sort object. */
- SORTING,
-
- /** Query will be used with Pageable object. */
- PAGINATION,
-
- /** No advanced option. */
- NONE
- }
-
- /**
- * Query text string.
- */
- private final String qrySql;
-
- /**
- * Whether this is a SQL fields query
- */
- private final boolean isFieldQuery;
-
- /**
- * Whether this is Text query
- */
- private final boolean isTextQuery;
-
- /**
- * Whether was autogenerated (by method name)
- */
- private final boolean isAutogenerated;
-
- /**
- * Type of option.
- */
- private final Option option;
-
- /**
- * @param qrySql the query string.
- * @param isFieldQuery Is field query.
- * @param isTextQuery Is a TextQuery
- * @param isAutogenerated query was autogenerated
- * @param option Option.
- */
- public IgniteQuery(String qrySql,
- boolean isFieldQuery,
- boolean isTextQuery,
- boolean isAutogenerated,
- Option option) {
- this.qrySql = qrySql;
- this.isFieldQuery = isFieldQuery;
- this.isTextQuery = isTextQuery;
- this.isAutogenerated = isAutogenerated;
- this.option = option;
- }
-
- /**
- * Text string of the query.
- *
- * @return SQL query text string.
- */
- public String qryStr() {
- return qrySql;
- }
-
- /**
- * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
- *
- * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
- */
- public boolean isFieldQuery() {
- return isFieldQuery;
- }
-
- /**
- * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
- *
- * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
- */
- public boolean isTextQuery() {
- return isTextQuery;
- }
-
- /**
- * Returns {@code true} if it's autogenerated, {@code false} otherwise.
- *
- * @return {@code true} if it's autogenerated, {@code false} otherwise.
- */
- public boolean isAutogenerated() {
- return isAutogenerated;
- }
-
- /**
- * Advanced querying option.
- *
- * @return querying option.
- */
- public Option options() {
- return option;
- }
-
- /** */
- @Override public String toString() {
- return S.toString(IgniteQuery.class, this);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java
deleted file mode 100644
index 864903a..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Method;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.mapping.PropertyPath;
-import org.springframework.data.mapping.PropertyReferenceException;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.parser.Part;
-import org.springframework.data.repository.query.parser.PartTree;
-
-/**
- * Ignite query generator for Spring Data framework.
- */
-public class IgniteQueryGenerator {
- /** */
- private IgniteQueryGenerator() {
- // No-op.
- }
-
- /**
- * @param mtd Method.
- * @param metadata Metadata.
- * @return Generated ignite query.
- */
- public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
- PartTree parts;
-
- try {
- parts = new PartTree(mtd.getName(), metadata.getDomainType());
- }
- catch (PropertyReferenceException e) {
- parts = new PartTree(mtd.getName(), metadata.getIdType());
- }
-
- boolean isCountOrFieldQuery = parts.isCountProjection();
-
- StringBuilder sql = new StringBuilder();
-
- if (parts.isDelete()) {
- sql.append("DELETE ");
-
- // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
- isCountOrFieldQuery = true;
- }
- else {
- sql.append("SELECT ");
-
- if (parts.isDistinct())
- throw new UnsupportedOperationException("DISTINCT clause in not supported.");
-
- if (isCountOrFieldQuery)
- sql.append("COUNT(1) ");
- else
- sql.append("* ");
- }
-
- sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
-
- if (parts.iterator().hasNext()) {
- sql.append(" WHERE ");
-
- for (PartTree.OrPart orPart : parts) {
- sql.append("(");
-
- for (Part part : orPart) {
- handleQueryPart(sql, part, metadata.getDomainType());
- sql.append(" AND ");
- }
-
- sql.delete(sql.length() - 5, sql.length());
-
- sql.append(") OR ");
- }
-
- sql.delete(sql.length() - 4, sql.length());
- }
-
- addSorting(sql, parts.getSort());
-
- if (parts.isLimiting()) {
- sql.append(" LIMIT ");
- sql.append(parts.getMaxResults().intValue());
- }
-
- return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
- }
-
- /**
- * Add a dynamic part of query for the sorting support.
- *
- * @param sql SQL text string.
- * @param sort Sort method.
- * @return Sorting criteria in StringBuilder.
- */
- public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
- if (sort != null && sort != Sort.unsorted()) {
- sql.append(" ORDER BY ");
-
- for (Sort.Order order : sort) {
- sql.append(order.getProperty()).append(" ").append(order.getDirection());
-
- if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
- sql.append(" ").append("NULL ");
-
- switch (order.getNullHandling()) {
- case NULLS_FIRST:
- sql.append("FIRST");
- break;
- case NULLS_LAST:
- sql.append("LAST");
- break;
- default:
- }
- }
- sql.append(", ");
- }
-
- sql.delete(sql.length() - 2, sql.length());
- }
-
- return sql;
- }
-
- /**
- * Add a dynamic part of a query for the pagination support.
- *
- * @param sql Builder instance.
- * @param pageable Pageable instance.
- * @return Builder instance.
- */
- public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
-
- addSorting(sql, pageable.getSort());
-
- sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
-
- return sql;
- }
-
- /**
- * Determines whether query is dynamic or not (by list of method parameters)
- *
- * @param mtd Method.
- * @return type of options
- */
- public static IgniteQuery.Option getOptions(Method mtd) {
- IgniteQuery.Option option = IgniteQuery.Option.NONE;
-
- Class<?>[] types = mtd.getParameterTypes();
- if (types.length > 0) {
- Class<?> type = types[types.length - 1];
-
- if (Sort.class.isAssignableFrom(type))
- option = IgniteQuery.Option.SORTING;
- else if (Pageable.class.isAssignableFrom(type))
- option = IgniteQuery.Option.PAGINATION;
- }
-
- for (int i = 0; i < types.length - 1; i++) {
- Class<?> tp = types[i];
-
- if (tp == Sort.class || tp == Pageable.class)
- throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
- }
-
- return option;
- }
-
- /**
- * Check and correct table name if using column name from compound key.
- */
- private static String getColumnName(Part part, Class<?> domainType) {
- PropertyPath prperty = part.getProperty();
-
- if (prperty.getType() != domainType)
- return domainType.getSimpleName() + "." + prperty.getSegment();
- else
- return part.toString();
- }
-
- /**
- * Transform part to qryStr expression
- */
- private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
- sql.append("(");
-
- sql.append(getColumnName(part, domainType));
-
- switch (part.getType()) {
- case SIMPLE_PROPERTY:
- sql.append("=?");
- break;
- case NEGATING_SIMPLE_PROPERTY:
- sql.append("<>?");
- break;
- case GREATER_THAN:
- sql.append(">?");
- break;
- case GREATER_THAN_EQUAL:
- sql.append(">=?");
- break;
- case LESS_THAN:
- sql.append("<?");
- break;
- case LESS_THAN_EQUAL:
- sql.append("<=?");
- break;
- case IS_NOT_NULL:
- sql.append(" IS NOT NULL");
- break;
- case IS_NULL:
- sql.append(" IS NULL");
- break;
- case BETWEEN:
- sql.append(" BETWEEN ? AND ?");
- break;
- case FALSE:
- sql.append(" = FALSE");
- break;
- case TRUE:
- sql.append(" = TRUE");
- break;
- //TODO: review this legacy code, LIKE should be -> LIKE ?
- case LIKE:
- case CONTAINING:
- sql.append(" LIKE '%' || ? || '%'");
- break;
- case NOT_CONTAINING:
- //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
- case NOT_LIKE:
- sql.append(" NOT LIKE '%' || ? || '%'");
- break;
- case STARTING_WITH:
- sql.append(" LIKE ? || '%'");
- break;
- case ENDING_WITH:
- sql.append(" LIKE '%' || ?");
- break;
- case IN:
- sql.append(" IN ?");
- break;
- case NOT_IN:
- sql.append(" NOT IN ?");
- break;
- case REGEX:
- sql.append(" REGEXP ?");
- break;
- case NEAR:
- case AFTER:
- case BEFORE:
- case EXISTS:
- default:
- throw new UnsupportedOperationException(part.getType() + " is not supported!");
- }
-
- sql.append(")");
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
deleted file mode 100644
index 2724940..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.cache.Cache;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.reflect.FieldUtils;
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.cache.query.FieldsQueryCursor;
-import org.apache.ignite.cache.query.Query;
-import org.apache.ignite.cache.query.QueryCursor;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.cache.query.SqlQuery;
-import org.apache.ignite.cache.query.TextQuery;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.springdata20.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata20.repository.query.StringQuery.ParameterBinding;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.SliceImpl;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.projection.ProjectionFactory;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameter;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.StringUtils;
-
-import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
-import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
-import static org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactory.isFieldQuery;
-
-/**
- * Ignite query implementation.
- * <p>
- * <p>
- * Features:
- * <ol>
- * <li> Supports query tuning parameters</li>
- * <li> Supports projections</li>
- * <li> Supports Page and Stream responses</li>
- * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
- * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
- * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
- * <ol>
- * <li><b>Template variables</b>:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the domain entity</li>
- * </ol>
- * </li>
- * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
- * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
- * ?#{[0]} or ?#{#myParamName}</li>
- * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
- * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
- * through SpEL EvaluationContext extension model.</li>
- * </ol>
- * Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
- * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
- * Pageable pageable);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
- * User searchUserByEmail(String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
- * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
- * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
- * <pre>
- * {@code @Query}(textQuery = true, value = "email: #{#email}")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
- * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{[0]}")
- * List<User> searchUsersByText(String textToSearch, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
- * .match('city', #city)).build()}")
- * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
- *
- * {@code @Query}(dynamicQuery = true)
- * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
- * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
- *
- * ...
- * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
- * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
- *
- * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
- * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
- *
- * </pre>
- * </li>
- * </ol>
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@SuppressWarnings("unchecked")
-public class IgniteRepositoryQuery implements RepositoryQuery {
- /**
- * Defines the way how to process query result
- */
- private enum ReturnStrategy {
- /** Need to return only one value. */
- ONE_VALUE,
-
- /** Need to return one cache entry */
- CACHE_ENTRY,
-
- /** Need to return list of cache entries */
- LIST_OF_CACHE_ENTRIES,
-
- /** Need to return list of values */
- LIST_OF_VALUES,
-
- /** Need to return list of lists */
- LIST_OF_LISTS,
-
- /** Need to return slice */
- SLICE_OF_VALUES,
-
- /** Slice of cache entries */
- SLICE_OF_CACHE_ENTRIES,
-
- /** Slice of lists */
- SLICE_OF_LISTS,
-
- /** Need to return Page of values */
- PAGE_OF_VALUES,
-
- /** Need to return stream of values */
- STREAM_OF_VALUES,
- }
-
- /** */
- private final Class<?> type;
-
- /** Domain entitiy field descriptors mapped to their names in lower case. */
- private final Map<String, Field> domainEntitiyFields;
-
- /** */
- private final IgniteQuery staticQuery;
-
- /** */
- private final IgniteCacheProxy<?, ?> cache;
-
- /** */
- private final Method mtd;
-
- /** */
- private final RepositoryMetadata metadata;
-
- /** */
- private final ProjectionFactory factory;
-
- /** */
- private final ReturnStrategy staticReturnStgy;
-
- /** Detect if returned data from method is projected */
- private final boolean hasProjection;
-
- /** Whether projection is dynamic (provided as method parameter) */
- private final boolean hasDynamicProjection;
-
- /** Dynamic projection parameter index */
- private final int dynamicProjectionIndex;
-
- /** Dynamic query configuration */
- private final int dynamicQueryConfigurationIndex;
-
- /** The return query method */
- private final QueryMethod qMethod;
-
- /** The return domain class of QueryMethod */
- private final Class<?> returnedDomainClass;
-
- /** */
- private final SpelExpressionParser expressionParser;
-
- /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
- private final EvaluationContextProvider queryMethodEvaluationContextProvider;
-
- /** Static query configuration. */
- private final DynamicQueryConfig staticQueryConfiguration;
-
- /**
- * Instantiates a new Ignite repository query.
- *
- * @param metadata Metadata.
- * @param staticQuery Query.
- * @param mtd Method.
- * @param factory Factory.
- * @param cache Cache.
- * @param staticQueryConfiguration the query configuration
- * @param queryMethodEvaluationContextProvider the query method evaluation context provider
- */
- public IgniteRepositoryQuery(
- RepositoryMetadata metadata,
- @Nullable IgniteQuery staticQuery,
- Method mtd,
- ProjectionFactory factory,
- IgniteCacheProxy<? ,?> cache,
- @Nullable DynamicQueryConfig staticQueryConfiguration,
- EvaluationContextProvider queryMethodEvaluationContextProvider) {
- this.metadata = metadata;
- this.mtd = mtd;
- this.factory = factory;
- type = metadata.getDomainType();
-
- domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
- .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
-
- this.cache = cache;
-
- this.staticQueryConfiguration = staticQueryConfiguration;
- this.staticQuery = staticQuery;
-
- if (this.staticQuery != null)
- staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
- else
- staticReturnStgy = null;
-
- expressionParser = new SpelExpressionParser();
- this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
-
- qMethod = getQueryMethod();
-
- // control projection
- hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
- hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
- .isProjecting();
-
- dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
-
- returnedDomainClass = getQueryMethod().getReturnedObjectType();
-
- dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
-
- // ensure dynamic query configuration param exists if dynamicQuery = true
- if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
- throw new IllegalStateException(
- "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
- + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
- }
- }
-
- /**
- * {@inheritDoc} @param values the values
- *
- * @return the object
- */
- @Override public Object execute(Object[] values) {
- Object[] parameters = values;
-
- // config via Query annotation (dynamicQuery = false)
- DynamicQueryConfig config = staticQueryConfiguration;
-
- // or condition to allow query tunning
- if (config == null || dynamicQueryConfigurationIndex != -1) {
- DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
- parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
- if (newConfig != null) {
- // upset query configuration
- config = newConfig;
- }
- }
- // query configuration is required, via Query annotation or per parameter (within provided values param)
- if (config == null) {
- throw new IllegalStateException(
- "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
- + ".repository.config.Query annotation, you must provide a non null method parameter of type "
- + "DynamicQueryConfig");
- }
-
- IgniteQuery qry = getQuery(config);
-
- ReturnStrategy returnStgy = getReturnStgy(qry);
-
- Query iQry = prepareQuery(qry, config, returnStgy, parameters);
-
- QueryCursor qryCursor;
-
- try {
- qryCursor = cache.query(iQry);
- }
- catch (IllegalArgumentException e) {
- if (cache instanceof IgniteClientCacheProxy) {
- throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
- " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
- iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
- }
-
- throw e;
- }
-
- return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
- }
-
- /** {@inheritDoc} */
- @Override public QueryMethod getQueryMethod() {
- return new QueryMethod(mtd, metadata, factory);
- }
-
- private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
- Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
- int i = 0;
- boolean found = false;
- int index = -1;
- while (it.hasNext()) {
- T parameter = it.next();
-
- if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
- if (found) {
- throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
- + "Only ONE DynamicQueryConfig parameter is allowed");
- }
-
- found = true;
- index = i;
- }
-
- i++;
- }
- return index;
- }
-
- /**
- * @param mtd Method.
- * @param isFieldQry Is field query.
- * @return Return strategy type.
- */
- private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
- Class<?> returnType = mtd.getReturnType();
-
- if (returnType == Slice.class) {
- if (isFieldQry) {
- if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
- return ReturnStrategy.SLICE_OF_LISTS;
- }
- else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
- return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
- return ReturnStrategy.SLICE_OF_VALUES;
- }
- else if (returnType == Page.class)
- return ReturnStrategy.PAGE_OF_VALUES;
- else if (returnType == Stream.class)
- return ReturnStrategy.STREAM_OF_VALUES;
- else if (Cache.Entry.class.isAssignableFrom(returnType))
- return ReturnStrategy.CACHE_ENTRY;
- else if (Iterable.class.isAssignableFrom(returnType)) {
- if (isFieldQry) {
- if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
- return ReturnStrategy.LIST_OF_LISTS;
- }
- else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
- return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
- return ReturnStrategy.LIST_OF_VALUES;
- }
- else
- return ReturnStrategy.ONE_VALUE;
- }
-
- /**
- * @param cls Class.
- * @param mtd Method.
- * @return if {@code mtd} return type is assignable from {@code cls}
- */
- private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
- Type genericReturnType = mtd.getGenericReturnType();
-
- if (!(genericReturnType instanceof ParameterizedType))
- return false;
-
- Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
-
- if (actualTypeArguments.length == 0)
- return false;
-
- if (actualTypeArguments[0] instanceof ParameterizedType) {
- ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
-
- Class<?> type1 = (Class)type.getRawType();
-
- return type1.isAssignableFrom(cls);
- }
-
- if (actualTypeArguments[0] instanceof Class) {
- Class typeArg = (Class)actualTypeArguments[0];
-
- return typeArg.isAssignableFrom(cls);
- }
-
- return false;
- }
-
- /**
- * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
- *
- * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
- * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
- */
- private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
- if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
- return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
-
- return (T)object;
- }
-
- /**
- * @param cfg Config.
- */
- private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
- if (staticQuery != null)
- return staticQuery;
-
- if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
- return new IgniteQuery(cfg.value(),
- !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
- false, IgniteQueryGenerator.getOptions(mtd));
- }
-
- throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
- + ".apache.ignite.springdata.repository.config.Query annotation, you must"
- + " provide a non null method parameter of type DynamicQueryConfig with a "
- + "non empty value (query string) or textQuery = true");
- }
-
- /**
- * @param qry Query.
- */
- private ReturnStrategy getReturnStgy(IgniteQuery qry) {
- if (staticReturnStgy != null)
- return staticReturnStgy;
-
- if (qry != null)
- return calcReturnType(mtd, qry.isFieldQuery());
-
- throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
- + "via org.apache.ignite.springdata.repository.config.Query annotation, "
- + "you must provide a non null method parameter of type "
- + "DynamicQueryConfig with a non empty value (query string) or textQuery "
- + "= true");
- }
-
- /**
- * @param cls Class.
- */
- private static boolean isPrimitiveOrWrapper(Class<?> cls) {
- return cls.isPrimitive() ||
- Boolean.class.equals(cls) ||
- Byte.class.equals(cls) ||
- Character.class.equals(cls) ||
- Short.class.equals(cls) ||
- Integer.class.equals(cls) ||
- Long.class.equals(cls) ||
- Float.class.equals(cls) ||
- Double.class.equals(cls) ||
- Void.class.equals(cls) ||
- String.class.equals(cls) ||
- UUID.class.equals(cls);
- }
-
- /**
- * @param prmtrs Prmtrs.
- * @param qryCursor Query cursor.
- * @return Query cursor or slice
- */
- @Nullable
- private Object transformQueryCursor(IgniteQuery qry,
- ReturnStrategy returnStgy,
- Object[] prmtrs,
- QueryCursor qryCursor) {
- final Class<?> returnClass;
-
- if (hasProjection) {
- if (hasDynamicProjection)
- returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
- else
- returnClass = returnedDomainClass;
- }
- else
- returnClass = returnedDomainClass;
-
- if (qry.isFieldQuery()) {
- // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
- boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
-
- FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
-
- Function<List<?>, ?> cWrapperTransformFunction = null;
-
- if (type.equals(returnClass))
- cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
- else {
- if (hasProjection || singlePrimitiveResult) {
- if (singlePrimitiveResult)
- cWrapperTransformFunction = row -> row.get(0);
- else {
- // Map row -> projection class
- cWrapperTransformFunction = row -> factory
- .createProjection(returnClass, rowToMap(row, fieldQryCur));
- }
- }
- else
- cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
- }
-
- QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
- cWrapperTransformFunction);
-
- switch (returnStgy) {
- case PAGE_OF_VALUES:
- return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
- case LIST_OF_VALUES:
- return cWrapper.getAll();
- case STREAM_OF_VALUES:
- return cWrapper.stream();
- case ONE_VALUE:
- Iterator<?> iter = cWrapper.iterator();
- if (iter.hasNext()) {
- Object resp = iter.next();
- U.closeQuiet(cWrapper);
- return resp;
- }
- return null;
- case SLICE_OF_VALUES:
- return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case SLICE_OF_LISTS:
- return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case LIST_OF_LISTS:
- return qryCursor.getAll();
- default:
- throw new IllegalStateException();
- }
- }
- else {
- Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
-
- if (hasProjection && !type.equals(returnClass))
- cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
- else
- cWrapperTransformFunction = Cache.Entry::getValue;
-
- QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
- (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
-
- switch (returnStgy) {
- case PAGE_OF_VALUES:
- return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
- case LIST_OF_VALUES:
- return cWrapper.getAll();
- case STREAM_OF_VALUES:
- return cWrapper.stream();
- case ONE_VALUE:
- Iterator<?> iter1 = cWrapper.iterator();
- if (iter1.hasNext()) {
- Object resp = iter1.next();
- U.closeQuiet(cWrapper);
- return resp;
- }
- return null;
- case CACHE_ENTRY:
- Iterator<?> iter2 = qryCursor.iterator();
- if (iter2.hasNext()) {
- Object resp2 = iter2.next();
- U.closeQuiet(qryCursor);
- return resp2;
- }
- return null;
- case SLICE_OF_VALUES:
- return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case SLICE_OF_CACHE_ENTRIES:
- return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case LIST_OF_CACHE_ENTRIES:
- return qryCursor.getAll();
- default:
- throw new IllegalStateException();
- }
- }
- }
-
- /**
- * Extract bindable values
- *
- * @param values values invoking query method
- * @param queryMethodParams query method parameter definitions
- * @param queryBindings All parameters found on query string that need to be binded
- * @return new list of parameters
- */
- private Object[] extractBindableValues(Object[] values,
- Parameters<?, ?> queryMethodParams,
- List<ParameterBinding> queryBindings) {
- // no binding params then exit
- if (queryBindings.isEmpty())
- return values;
-
- Object[] newValues = new Object[queryBindings.size()];
-
- // map bindable parameters from query method: (index/name) - index
- HashMap<String, Integer> methodParams = new HashMap<>();
-
- // create an evaluation context for custom query
- EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
- .getEvaluationContext(queryMethodParams, values);
-
- // By default queryEvalContext:
- // - make accesible query method parameters by index:
- // @Query("select u from User u where u.age = ?#{[0]}")
- // List<User> findUsersByAge(int age);
- // - make accesible query method parameters by name:
- // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
- // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
-
- // query method param's index by name and position
- queryMethodParams.getBindableParameters().forEach(p -> {
- if (p.isNamedParameter()) {
- // map by name (annotated by @Param)
- methodParams.put(p.getName().get(), p.getIndex());
- }
- // map by position
- methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
- });
-
- // process all parameters on query and extract new values to bind
- for (int i = 0; i < queryBindings.size(); i++) {
- ParameterBinding p = queryBindings.get(i);
-
- if (p.isExpression()) {
- // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
- newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
- }
- else {
- // Extract parameter value by name or position respectively from invoking values
- newValues[i] = values[methodParams.get(
- p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
- }
- }
-
- return newValues;
- }
-
- /**
- * @param qry Query.
- * @param config Config.
- * @param returnStgy Return stgy.
- * @param values Values.
- * @return prepared query for execution
- */
- private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
- Object[] parameters = values;
-
- String queryString = qry.qryStr();
-
- Query query;
-
- checkRequiredPageable(returnStgy, values);
-
- if (!qry.isTextQuery()) {
- if (!qry.isAutogenerated()) {
- StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
- queryString = squery.getQueryString();
- parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
- squery.getParameterBindings());
- }
- else {
- // remove dynamic projection from parameters
- if (hasDynamicProjection)
- parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
- }
-
- switch (qry.options()) {
- case SORTING:
- queryString = IgniteQueryGenerator
- .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
- .toString();
- if (qry.isAutogenerated())
- parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
- break;
- case PAGINATION:
- queryString = IgniteQueryGenerator
- .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
- .toString();
- if (qry.isAutogenerated())
- parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
- break;
- default:
- }
-
- if (qry.isFieldQuery()) {
- SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
- sqlFieldsQry.setArgs(parameters);
-
- sqlFieldsQry.setCollocated(config.collocated());
- sqlFieldsQry.setDistributedJoins(config.distributedJoins());
- sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
- sqlFieldsQry.setLazy(config.lazy());
- sqlFieldsQry.setLocal(config.local());
-
- if (config.parts() != null && config.parts().length > 0)
- sqlFieldsQry.setPartitions(config.parts());
-
- sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
- query = sqlFieldsQry;
- }
- else {
- SqlQuery sqlQry = new SqlQuery(type, queryString);
- sqlQry.setArgs(parameters);
-
- sqlQry.setDistributedJoins(config.distributedJoins());
- sqlQry.setLocal(config.local());
-
- if (config.parts() != null && config.parts().length > 0)
- sqlQry.setPartitions(config.parts());
-
- sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
- query = sqlQry;
- }
- }
- else {
- int pageSize = -1;
-
- switch (qry.options()) {
- case PAGINATION:
- pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
- break;
- }
-
- // check if queryString contains SpEL template expressions and evaluate them if any
- if (queryString.contains("#{")) {
- EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
- .getEvaluationContext(getQueryMethod().getParameters(),
- values);
-
- Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
- .getValue(queryEvalContext);
-
- if (!(eval instanceof String)) {
- throw new IllegalStateException(
- "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
- .getName()
- + ". Please, check your expression: " + queryString);
- }
- queryString = (String)eval;
- }
-
- TextQuery textQuery = new TextQuery(type, queryString, config.limit());
-
- textQuery.setLocal(config.local());
-
- if (pageSize > -1)
- textQuery.setPageSize(pageSize);
-
- query = textQuery;
- }
- return query;
- }
-
- /**
- * @param row SQL result row.
- * @param cursor SQL query result cursor through which {@param row} was obtained.
- * @return SQL result row values mapped to corresponding column names.
- */
- private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
- // use treemap with case insensitive property name
- final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
- for (int i = 0; i < row.size(); i++) {
- // don't want key or val columns
- final String fieldName = cursor.getFieldName(i).toLowerCase();
-
- if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
- map.put(fieldName, row.get(i));
- }
-
- return map;
- }
-
- /**
- * convert row ( with list of field values) into domain entity
- *
- * @param row SQL query result row.
- * @param cursor SQL query result cursor through which {@param row} was obtained.
- * @return Entitiy instance.
- */
- private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
- Constructor<?> ctor;
-
- try {
- ctor = type.getDeclaredConstructor();
-
- ctor.setAccessible(true);
- }
- catch (NoSuchMethodException | SecurityException ignored) {
- ctor = null;
- }
-
- try {
- Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
-
- for (int i = 0; i < row.size(); i++) {
- Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
-
- if (entityField != null)
- FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
- }
-
- return (V)res;
- }
- catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
- throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
- }
- }
-
- /**
- * Validates operations that requires Pageable parameter
- *
- * @param returnStgy Return stgy.
- * @param prmtrs Prmtrs.
- */
- private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
- try {
- if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
- || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
- Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
- page.isPaged();
- }
- }
- catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
- throw new IllegalStateException(
- "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
- }
- }
-
- /**
- * Ignite QueryCursor wrapper.
- * <p>
- * Ensures closing underline cursor when there is no data.
- *
- * @param <T> input type
- * @param <V> transformed output type
- */
- public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
- /**
- * Delegate query cursor.
- */
- private final QueryCursor<T> delegate;
-
- /**
- * Transformer.
- */
- private final Function<T, V> transformer;
-
- /**
- * Instantiates a new Query cursor wrapper.
- *
- * @param delegate delegate QueryCursor with T input elements
- * @param transformer Function to transform T to V elements
- */
- public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
- this.delegate = delegate;
- this.transformer = transformer;
- }
-
- /** {@inheritDoc} */
- @Override public Iterator<V> iterator() {
- final Iterator<T> it = delegate.iterator();
-
- return new Iterator<V>() {
- /** */
- @Override public boolean hasNext() {
- if (!it.hasNext()) {
- U.closeQuiet(delegate);
- return false;
- }
- return true;
- }
-
- /** */
- @Override public V next() {
- final V r = transformer.apply(it.next());
- if (r != null)
- return r;
- throw new NoSuchElementException();
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override public void close() {
- U.closeQuiet(delegate);
- }
-
- /** {@inheritDoc} */
- @Override public List<V> getAll() {
- final List<V> data = new ArrayList<>();
- delegate.forEach(i -> data.add(transformer.apply(i)));
- U.closeQuiet(delegate);
- return data;
- }
-
- /** {@inheritDoc} */
- @Override public int size() {
- return 0;
- }
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java
deleted file mode 100644
index 40752b5..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.BiFunction;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext.SpelExtractor;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Range;
-import org.springframework.data.domain.Range.Bound;
-import org.springframework.data.repository.query.parser.Part.Type;
-import org.springframework.util.Assert;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-import static org.springframework.util.ObjectUtils.nullSafeEquals;
-import static org.springframework.util.ObjectUtils.nullSafeHashCode;
-
-/**
- * Encapsulation of a JPA query String. Offers access to parameters as bindings. The internal query String is cleaned
- * from decorated parameters like {@literal %:lastname%} and the matching bindings take care of applying the decorations
- * in the {@link ParameterBinding#prepare(Object)} method. Note that this class also handles replacing SpEL expressions
- * with synthetic bind parameters
- *
- * @author Oliver Gierke
- * @author Thomas Darimont
- * @author Oliver Wehrens
- * @author Mark Paluch
- * @author Jens Schauder
- */
-class StringQuery implements DeclaredQuery {
- /** */
- private final String query;
-
- /** */
- private final List<ParameterBinding> bindings;
-
- /** */
- @Nullable
- private final String alias;
-
- /** */
- private final boolean hasConstructorExpression;
-
- /** */
- private final boolean containsPageableInSpel;
-
- /** */
- private final boolean usesJdbcStyleParameters;
-
- /**
- * Creates a new {@link StringQuery} from the given JPQL query.
- *
- * @param query must not be {@literal null} or empty.
- */
- StringQuery(String query) {
- Assert.hasText(query, "Query must not be null or empty!");
-
- bindings = new ArrayList<>();
- containsPageableInSpel = query.contains("#pageable");
-
- Metadata queryMeta = new Metadata();
- this.query = ParameterBindingParser.INSTANCE
- .parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(query, bindings,
- queryMeta);
-
- usesJdbcStyleParameters = queryMeta.usesJdbcStyleParameters;
- alias = QueryUtils.detectAlias(query);
- hasConstructorExpression = QueryUtils.hasConstructorExpression(query);
- }
-
- /**
- * Returns whether we have found some like bindings.
- */
- boolean hasParameterBindings() {
- return !bindings.isEmpty();
- }
-
- /** */
- String getProjection() {
- return QueryUtils.getProjection(query);
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#getParameterBindings()
- /** {@inheritDoc} */
- @Override public List<ParameterBinding> getParameterBindings() {
- return bindings;
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#deriveCountQuery(java.lang.String, java.lang
- /** {@inheritDoc} */
- @Override public DeclaredQuery deriveCountQuery(@Nullable String countQuery,
- @Nullable String countQueryProjection) {
- return DeclaredQuery
- .of(countQuery != null ? countQuery : QueryUtils.createCountQueryFor(query, countQueryProjection));
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#usesJdbcStyleParameters()
- /** */
- @Override public boolean usesJdbcStyleParameters() {
- return usesJdbcStyleParameters;
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#getQueryString()
- /** {@inheritDoc} */
- @Override public String getQueryString() {
- return query;
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#getAlias()
- /** {@inheritDoc} */
- @Override @Nullable
- public String getAlias() {
- return alias;
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#hasConstructorExpression()
- /** {@inheritDoc} */
- @Override public boolean hasConstructorExpression() {
- return hasConstructorExpression;
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#isDefaultProjection()
- /** {@inheritDoc} */
- @Override public boolean isDefaultProjection() {
- return getProjection().equalsIgnoreCase(alias);
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#hasNamedParameter()
- /** {@inheritDoc} */
- @Override public boolean hasNamedParameter() {
- return bindings.stream().anyMatch(b -> b.getName() != null);
- }
-
- // See org.springframework.data.jpa.repository.query.DeclaredQuery#usesPaging()
- /** {@inheritDoc} */
- @Override public boolean usesPaging() {
- return containsPageableInSpel;
- }
-
- /**
- * A parser that extracts the parameter bindings from a given query string.
- *
- * @author Thomas Darimont
- */
- enum ParameterBindingParser {
- /** */
- INSTANCE;
-
- /** */
- private static final String EXPRESSION_PARAMETER_PREFIX = "__$synthetic$__";
-
- /** */
- public static final String POSITIONAL_OR_INDEXED_PARAMETER = "\\?(\\d*+(?![#\\w]))";
- // .....................................................................^ not followed by a hash or a letter.
- // .................................................................^ zero or more digits.
- // .............................................................^ start with a question mark.
-
- /** */
- private static final Pattern PARAMETER_BINDING_BY_INDEX = Pattern.compile(POSITIONAL_OR_INDEXED_PARAMETER);
-
- /** */
- private static final Pattern PARAMETER_BINDING_PATTERN;
-
- /** */
- private static final String MESSAGE =
- "Already found parameter binding with same index / parameter name but differing binding type! "
- + "Already have: %s, found %s! If you bind a parameter multiple times make sure they use the same "
- + "binding.";
-
- /** */
- private static final int INDEXED_PARAMETER_GROUP = 4;
-
- /** */
- private static final int NAMED_PARAMETER_GROUP = 6;
-
- /** */
- private static final int COMPARISION_TYPE_GROUP = 1;
-
- static {
- List<String> keywords = new ArrayList<>();
-
- for (ParameterBindingType type : ParameterBindingType.values()) {
- if (type.getKeyword() != null) {
- keywords.add(type.getKeyword());
- }
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("(");
- builder.append(StringUtils.collectionToDelimitedString(keywords, "|")); // keywords
- builder.append(")?");
- builder.append("(?: )?"); // some whitespace
- builder.append("\\(?"); // optional braces around parameters
- builder.append("(");
- builder.append("%?(" + POSITIONAL_OR_INDEXED_PARAMETER + ")%?"); // position parameter and parameter index
- builder.append("|"); // or
-
- // named parameter and the parameter name
- builder.append("%?(" + QueryUtils.COLON_NO_DOUBLE_COLON + QueryUtils.IDENTIFIER_GROUP + ")%?");
-
- builder.append(")");
- builder.append("\\)?"); // optional braces around parameters
-
- PARAMETER_BINDING_PATTERN = Pattern.compile(builder.toString(), CASE_INSENSITIVE);
- }
-
- /**
- * Parses {@link ParameterBinding} instances from the given query and adds them to the registered bindings.
- * Returns the cleaned up query.
- */
- private String parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(String query,
- List<ParameterBinding> bindings,
- Metadata queryMeta) {
- int greatestParamIdx = tryFindGreatestParameterIndexIn(query);
- boolean parametersShouldBeAccessedByIdx = greatestParamIdx != -1;
-
- /*
- * Prefer indexed access over named parameters if only SpEL Expression parameters are present.
- */
- if (!parametersShouldBeAccessedByIdx && query.contains("?#{")) {
- parametersShouldBeAccessedByIdx = true;
- greatestParamIdx = 0;
- }
-
- SpelExtractor spelExtractor = createSpelExtractor(query, parametersShouldBeAccessedByIdx,
- greatestParamIdx);
-
- String resultingQry = spelExtractor.getQueryString();
- Matcher matcher = PARAMETER_BINDING_PATTERN.matcher(resultingQry);
- QuotationMap quotedAreas = new QuotationMap(resultingQry);
-
- int expressionParamIdx = parametersShouldBeAccessedByIdx ? greatestParamIdx : 0;
-
- boolean usesJpaStyleParameters = false;
-
- while (matcher.find()) {
- if (quotedAreas.isQuoted(matcher.start()))
- continue;
-
- String paramIdxStr = matcher.group(INDEXED_PARAMETER_GROUP);
- String paramName = paramIdxStr != null ? null : matcher.group(NAMED_PARAMETER_GROUP);
- Integer paramIdx = getParameterIndex(paramIdxStr);
-
- String typeSrc = matcher.group(COMPARISION_TYPE_GROUP);
- String expression = spelExtractor
- .getParameter(paramName == null ? paramIdxStr : paramName);
- String replacement = null;
-
- Assert.isTrue(paramIdxStr != null || paramName != null,
- () -> String.format("We need either a name or an index! Offending query string: %s", query));
-
- expressionParamIdx++;
- if (paramIdxStr != null && paramIdxStr.isEmpty()) {
- queryMeta.usesJdbcStyleParameters = true;
- paramIdx = expressionParamIdx;
- }
- else
- usesJpaStyleParameters = true;
-
- // named parameters (:param) will be untouched by spelExtractor, so replace them by ? as we don't
- // know position
- if (paramName != null)
- replacement = "?";
-
- if (usesJpaStyleParameters && queryMeta.usesJdbcStyleParameters) {
- throw new IllegalArgumentException(
- "Mixing of ? (? or :myNamedParam) parameters and other forms like ?1 (SpEL espressions or "
- + "indexed) is not supported!. Please, if you are using expressions or "
- + "indexed params, replace all named parameters by expressions. Example :myNamedParam "
- + "by ?#{#myNamedParam}.");
- }
-
- switch (ParameterBindingType.of(typeSrc)) {
- case LIKE:
- Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2));
- replacement = matcher.group(3);
-
- if (paramIdx != null)
- checkAndRegister(new LikeParameterBinding(paramIdx, likeType, expression), bindings);
- else {
- checkAndRegister(new LikeParameterBinding(paramName, likeType, expression), bindings);
-
- replacement = expression != null ? ":" + paramName : matcher.group(5);
- }
-
- break;
-
- case IN:
- if (paramIdx != null)
- checkAndRegister(new InParameterBinding(paramIdx, expression), bindings);
- else
- checkAndRegister(new InParameterBinding(paramName, expression), bindings);
-
- break;
-
- case AS_IS: // fall-through we don't need a special parameter binding for the given parameter.
- default:
- bindings.add(paramIdx != null
- ? new ParameterBinding(null, paramIdx, expression)
- : new ParameterBinding(paramName, null, expression));
- }
-
- if (replacement != null)
- resultingQry = replaceFirst(resultingQry, matcher.group(2), replacement);
- }
-
- return resultingQry;
- }
-
- /** */
- private static SpelExtractor createSpelExtractor(String queryWithSpel,
- boolean parametersShouldBeAccessedByIndex,
- int greatestParameterIndex) {
-
- /*
- * If parameters need to be bound by index, we bind the synthetic expression parameters starting from
- * position of the greatest discovered index parameter in order to
- * not mix-up with the actual parameter indices.
- */
- int expressionParameterIndex = parametersShouldBeAccessedByIndex ? greatestParameterIndex : 0;
-
- BiFunction<Integer, String, String> indexToParameterName = parametersShouldBeAccessedByIndex
- ? (index, expression) -> String.valueOf(
- index + expressionParameterIndex + 1)
- : (index, expression) ->
- EXPRESSION_PARAMETER_PREFIX + (index
- + 1);
-
- String fixedPrefix = parametersShouldBeAccessedByIndex ? "?" : ":";
-
- BiFunction<String, String, String> parameterNameToReplacement = (prefix, name) -> fixedPrefix + name;
-
- return SpelQueryContext.of(indexToParameterName, parameterNameToReplacement).parse(queryWithSpel);
- }
-
- /** */
- private static String replaceFirst(String text, String substring, String replacement) {
- int index = text.indexOf(substring);
- if (index < 0)
- return text;
-
- return text.substring(0, index) + replacement + text.substring(index + substring.length());
- }
-
- /** */
- @Nullable
- private static Integer getParameterIndex(@Nullable String parameterIndexString) {
- if (parameterIndexString == null || parameterIndexString.isEmpty())
- return null;
- return Integer.valueOf(parameterIndexString);
- }
-
- /** */
- private static int tryFindGreatestParameterIndexIn(String query) {
- Matcher parameterIndexMatcher = PARAMETER_BINDING_BY_INDEX.matcher(query);
-
- int greatestParameterIndex = -1;
- while (parameterIndexMatcher.find()) {
-
- String parameterIndexString = parameterIndexMatcher.group(1);
- Integer parameterIndex = getParameterIndex(parameterIndexString);
- if (parameterIndex != null)
- greatestParameterIndex = Math.max(greatestParameterIndex, parameterIndex);
- }
-
- return greatestParameterIndex;
- }
-
- /** */
- private static void checkAndRegister(ParameterBinding binding, List<ParameterBinding> bindings) {
-
- bindings.stream() //
- .filter(it -> it.hasName(binding.getName()) || it.hasPosition(binding.getPosition())) //
- .forEach(it -> Assert.isTrue(it.equals(binding), String.format(MESSAGE, it, binding)));
-
- if (!bindings.contains(binding))
- bindings.add(binding);
- }
-
- /**
- * An enum for the different types of bindings.
- *
- * @author Thomas Darimont
- * @author Oliver Gierke
- */
- private enum ParameterBindingType {
- // Trailing whitespace is intentional to reflect that the keywords must be used with at least one whitespace
- // character, while = does not.
- /** */
- LIKE("like "),
-
- /** */
- IN("in "),
-
- /** */
- AS_IS(null);
-
- /** */
- @Nullable
- private final String keyword;
-
- /** */
- ParameterBindingType(@Nullable String keyword) {
- this.keyword = keyword;
- }
-
- /**
- * Returns the keyword that will tirgger the binding type or {@literal null} if the type is not triggered by
- * a keyword.
- *
- * @return the keyword
- */
- @Nullable
- public String getKeyword() {
- return keyword;
- }
-
- /**
- * Return the appropriate {@link ParameterBindingType} for the given {@link String}. Returns {@literal
- * #AS_IS} in case no other {@link ParameterBindingType} could be found.
- */
- static ParameterBindingType of(String typeSource) {
- if (!StringUtils.hasText(typeSource))
- return AS_IS;
-
- for (ParameterBindingType type : values()) {
- if (type.name().equalsIgnoreCase(typeSource.trim()))
- return type;
- }
-
- throw new IllegalArgumentException(String.format("Unsupported parameter binding type %s!", typeSource));
- }
- }
- }
-
- /**
- * A generic parameter binding with name or position information.
- *
- * @author Thomas Darimont
- */
- static class ParameterBinding {
- /** */
- @Nullable
- private final String name;
-
- /** */
- @Nullable
- private final String expression;
-
- /** */
- @Nullable
- private final Integer position;
-
- /**
- * Creates a new {@link ParameterBinding} for the parameter with the given position.
- *
- * @param position must not be {@literal null}.
- */
- ParameterBinding(Integer position) {
- this(null, position, null);
- }
-
- /**
- * Creates a new {@link ParameterBinding} for the parameter with the given name, position and expression
- * information. Either {@literal name} or {@literal position} must be not {@literal null}.
- *
- * @param name of the parameter may be {@literal null}.
- * @param position of the parameter may be {@literal null}.
- * @param expression the expression to apply to any value for this parameter.
- */
- ParameterBinding(@Nullable String name, @Nullable Integer position, @Nullable String expression) {
-
- if (name == null)
- Assert.notNull(position, "Position must not be null!");
-
- if (position == null)
- Assert.notNull(name, "Name must not be null!");
-
- this.name = name;
- this.position = position;
- this.expression = expression;
- }
-
- /**
- * Returns whether the binding has the given name. Will always be {@literal false} in case the {@link
- * ParameterBinding} has been set up from a position.
- */
- boolean hasName(@Nullable String name) {
- return position == null && this.name != null && this.name.equals(name);
- }
-
- /**
- * Returns whether the binding has the given position. Will always be {@literal false} in case the {@link
- * ParameterBinding} has been set up from a name.
- */
- boolean hasPosition(@Nullable Integer position) {
- return position != null && name == null && position.equals(this.position);
- }
-
- /**
- * @return the name
- */
- @Nullable
- public String getName() {
- return name;
- }
-
- /**
- * @return the name
- * @throws IllegalStateException if the name is not available.
- */
- String getRequiredName() throws IllegalStateException {
-
- String name = getName();
-
- if (name != null)
- return name;
-
- throw new IllegalStateException(String.format("Required name for %s not available!", this));
- }
-
- /**
- * @return the position
- */
- @Nullable
- Integer getPosition() {
- return position;
- }
-
- /**
- * @return the position
- * @throws IllegalStateException if the position is not available.
- */
- int getRequiredPosition() throws IllegalStateException {
-
- Integer position = getPosition();
-
- if (position != null)
- return position;
-
- throw new IllegalStateException(String.format("Required position for %s not available!", this));
- }
-
- /**
- * @return {@literal true} if this parameter binding is a synthetic SpEL expression.
- */
- public boolean isExpression() {
- return expression != null;
- }
-
- /** */
- @Override public int hashCode() {
-
- int result = 17;
-
- result += nullSafeHashCode(name);
- result += nullSafeHashCode(position);
- result += nullSafeHashCode(expression);
-
- return result;
- }
-
- /** */
- @Override public boolean equals(Object obj) {
-
- if (!(obj instanceof ParameterBinding))
- return false;
-
- ParameterBinding that = (ParameterBinding)obj;
-
- return nullSafeEquals(name, that.name) && nullSafeEquals(position, that.position)
- && nullSafeEquals(expression, that.expression);
- }
-
- /** */
- @Override public String toString() {
- return String.format("ParameterBinding [name: %s, position: %d, expression: %s]", getName(), getPosition(),
- getExpression());
- }
-
- /**
- * @param valueToBind value to prepare
- */
- @Nullable
- public Object prepare(@Nullable Object valueToBind) {
- return valueToBind;
- }
-
- /** */
- @Nullable
- public String getExpression() {
- return expression;
- }
- }
-
- /**
- * Represents a {@link ParameterBinding} in a JPQL query augmented with instructions of how to apply a parameter as
- * an {@code IN} parameter.
- *
- * @author Thomas Darimont
- */
- static class InParameterBinding extends ParameterBinding {
- /**
- * Creates a new {@link InParameterBinding} for the parameter with the given name.
- */
- InParameterBinding(String name, @Nullable String expression) {
- super(name, null, expression);
- }
-
- /**
- * Creates a new {@link InParameterBinding} for the parameter with the given position.
- */
- InParameterBinding(int position, @Nullable String expression) {
- super(null, position, expression);
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding#prepare(java.lang.Object)
- */
- @Override public Object prepare(@Nullable Object value) {
- if (!ObjectUtils.isArray(value))
- return value;
-
- int length = Array.getLength(value);
- Collection<Object> result = new ArrayList<>(length);
-
- for (int i = 0; i < length; i++)
- result.add(Array.get(value, i));
-
- return result;
- }
-
- }
-
- /**
- * Represents a parameter binding in a JPQL query augmented with instructions of how to apply a parameter as LIKE
- * parameter. This allows expressions like {@code …like %?1} in the JPQL query, which is not allowed by plain JPA.
- *
- * @author Oliver Gierke
- * @author Thomas Darimont
- */
- static class LikeParameterBinding extends ParameterBinding {
- /** */
- private static final List<Type> SUPPORTED_TYPES = Arrays.asList(Type.CONTAINING, Type.STARTING_WITH,
- Type.ENDING_WITH, Type.LIKE);
-
- /** */
- private final Type type;
-
- /**
- * Creates a new {@link LikeParameterBinding} for the parameter with the given name and {@link Type}.
- *
- * @param name must not be {@literal null} or empty.
- * @param type must not be {@literal null}.
- */
- LikeParameterBinding(String name, Type type) {
- this(name, type, null);
- }
-
- /**
- * Creates a new {@link LikeParameterBinding} for the parameter with the given name and {@link Type} and
- * parameter binding input.
- *
- * @param name must not be {@literal null} or empty.
- * @param type must not be {@literal null}.
- * @param expression may be {@literal null}.
- */
- LikeParameterBinding(String name, Type type, @Nullable String expression) {
-
- super(name, null, expression);
-
- Assert.hasText(name, "Name must not be null or empty!");
- Assert.notNull(type, "Type must not be null!");
-
- Assert.isTrue(SUPPORTED_TYPES.contains(type), String.format("Type must be one of %s!",
- StringUtils.collectionToCommaDelimitedString(SUPPORTED_TYPES)));
-
- this.type = type;
- }
-
- /**
- * Creates a new {@link LikeParameterBinding} for the parameter with the given position and {@link Type}.
- *
- * @param position position of the parameter in the query.
- * @param type must not be {@literal null}.
- */
- LikeParameterBinding(int position, Type type) {
- this(position, type, null);
- }
-
- /**
- * Creates a new {@link LikeParameterBinding} for the parameter with the given position and {@link Type}.
- *
- * @param position position of the parameter in the query.
- * @param type must not be {@literal null}.
- * @param expression may be {@literal null}.
- */
- LikeParameterBinding(int position, Type type, @Nullable String expression) {
-
- super(null, position, expression);
-
- Assert.isTrue(position > 0, "Position must be greater than zero!");
- Assert.notNull(type, "Type must not be null!");
-
- Assert.isTrue(SUPPORTED_TYPES.contains(type), String.format("Type must be one of %s!",
- StringUtils.collectionToCommaDelimitedString(SUPPORTED_TYPES)));
-
- this.type = type;
- }
-
- /**
- * Returns the {@link Type} of the binding.
- *
- * @return the type
- */
- public Type getType() {
- return type;
- }
-
- /**
- * Prepares the given raw keyword according to the like type.
- */
- @Nullable
- @Override public Object prepare(@Nullable Object value) {
- if (value == null)
- return null;
-
- switch (type) {
- case STARTING_WITH:
- return String.format("%s%%", value.toString());
- case ENDING_WITH:
- return String.format("%%%s", value.toString());
- case CONTAINING:
- return String.format("%%%s%%", value.toString());
- case LIKE:
- default:
- return value;
- }
- }
-
- /** */
- @Override public boolean equals(Object obj) {
- if (!(obj instanceof LikeParameterBinding))
- return false;
-
- LikeParameterBinding that = (LikeParameterBinding)obj;
-
- return super.equals(obj) && type.equals(that.type);
- }
-
- /** */
- @Override public int hashCode() {
-
- int result = super.hashCode();
-
- result += nullSafeHashCode(type);
-
- return result;
- }
-
- /** */
- @Override public String toString() {
- return String.format("LikeBinding [name: %s, position: %d, type: %s]", getName(), getPosition(), type);
- }
-
- /**
- * Extracts the like {@link Type} from the given JPA like expression.
- *
- * @param expression must not be {@literal null} or empty.
- */
- private static Type getLikeTypeFrom(String expression) {
-
- Assert.hasText(expression, "Expression must not be null or empty!");
-
- if (expression.matches("%.*%"))
- return Type.CONTAINING;
-
- if (expression.startsWith("%"))
- return Type.ENDING_WITH;
-
- if (expression.endsWith("%"))
- return Type.STARTING_WITH;
-
- return Type.LIKE;
- }
-
- }
-
- /** */
- static class Metadata {
- /**
- * Uses jdbc style parameters.
- */
- private boolean usesJdbcStyleParameters;
- }
-
- /**
- * Value object to analyze a {@link String} to determine the parts of the {@link String} that are quoted and offers
- * an API to query that information.
- *
- * @author Jens Schauder
- * @author Oliver Gierke
- */
- static class QuotationMap {
- /** */
- private static final Collection<Character> QUOTING_CHARACTERS = Arrays.asList('"', '\'');
-
- /** */
- private final List<Range<Integer>> quotedRanges = new ArrayList<>();
-
- /**
- * Creates a new instance for the query.
- *
- * @param query can be {@literal null}.
- */
- public QuotationMap(@Nullable String query) {
- if (query == null)
- return;
-
- Character inQuotation = null;
- int start = 0;
-
- for (int i = 0; i < query.length(); i++) {
- char currentChar = query.charAt(i);
-
- if (QUOTING_CHARACTERS.contains(currentChar)) {
- if (inQuotation == null) {
-
- inQuotation = currentChar;
- start = i;
- }
- else if (currentChar == inQuotation) {
- inQuotation = null;
-
- quotedRanges.add(Range.from(Bound.inclusive(start)).to(Bound.inclusive(i)));
- }
- }
- }
-
- if (inQuotation != null) {
- throw new IllegalArgumentException(
- String.format("The string <%s> starts a quoted range at %d, but never ends it.", query, start));
- }
- }
-
- /**
- * Checks if a given index is within a quoted range.
- *
- * @param idx to check if it is part of a quoted range.
- * @return whether the query contains a quoted range at {@literal index}.
- */
- public boolean isQuoted(int idx) {
- return quotedRanges.stream().anyMatch(r -> r.contains(idx));
- }
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java
deleted file mode 100644
index c9f90dc..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes classes that integrates with Apache Ignite SQL engine.
- */
-package org.apache.ignite.springdata20.repository.query;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java
deleted file mode 100644
index c442b68..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query.spel;
-
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext.SpelExtractor;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.Assert;
-
-/**
- * Evaluates SpEL expressions as extracted by the {@link SpelExtractor} based on parameter information from a method and
- * parameter values from a method call.
- *
- * @author Jens Schauder
- * @author Gerrit Meier
- * @author Oliver Gierke
- */
-public class SpelEvaluator {
- /** */
- private static final SpelExpressionParser PARSER = new SpelExpressionParser();
-
- /** */
- private final EvaluationContextProvider evaluationCtxProvider;
-
- /** */
- private final Parameters<?, ?> parameters;
-
- /** */
- private final SpelExtractor extractor;
-
- /**
- * @param evaluationCtxProvider Evaluation context provider.
- * @param parameters Parameters.
- * @param extractor Extractor.
- */
- public SpelEvaluator(EvaluationContextProvider evaluationCtxProvider,
- Parameters<?, ?> parameters,
- SpelExtractor extractor) {
- this.evaluationCtxProvider = evaluationCtxProvider;
- this.parameters = parameters;
- this.extractor = extractor;
- }
-
- /**
- * Evaluate all the SpEL expressions in {@link #parameters} based on values provided as an argument.
- *
- * @param values Parameter values. Must not be {@literal null}.
- * @return a map from parameter name to evaluated value. Guaranteed to be not {@literal null}.
- */
- public Map<String, Object> evaluate(Object[] values) {
- Assert.notNull(values, "Values must not be null.");
-
- EvaluationContext evaluationCtx = evaluationCtxProvider.getEvaluationContext(parameters, values);
-
- return extractor.getParameters().collect(Collectors.toMap(//
- Map.Entry::getKey, //
- it -> getSpElValue(evaluationCtx, it.getValue()) //
- ));
- }
-
- /**
- * Returns the query string produced by the intermediate SpEL expression collection step.
- *
- * @return the query string produced by the intermediate SpEL expression collection step
- */
- public String getQueryString() {
- return extractor.getQueryString();
- }
-
- /**
- * @param evaluationCtx Evaluation context.
- * @param expression Expression.
- */
- @Nullable
- private static Object getSpElValue(EvaluationContext evaluationCtx, String expression) {
- return PARSER.parseExpression(expression).getValue(evaluationCtx);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java
deleted file mode 100644
index 44bfec8..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query.spel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.BiFunction;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Range;
-import org.springframework.data.domain.Range.Bound;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.util.Assert;
-
-/**
- * Source of {@link SpelExtractor} encapsulating configuration often common for all queries.
- *
- * @author Jens Schauder
- * @author Gerrit Meier
- */
-public class SpelQueryContext {
- /** */
- private static final String SPEL_PATTERN_STRING = "([:?])#\\{([^}]+)}";
-
- /** */
- private static final Pattern SPEL_PATTERN = Pattern.compile(SPEL_PATTERN_STRING);
-
- /**
- * A function from the index of a SpEL expression in a query and the actual SpEL expression to the parameter name to
- * be used in place of the SpEL expression. A typical implementation is expected to look like
- * <code>(index, spel) -> "__some_placeholder_" + index</code>
- */
- private final BiFunction<Integer, String, String> paramNameSrc;
-
- /**
- * A function from a prefix used to demarcate a SpEL expression in a query and a parameter name as returned from
- * {@link #paramNameSrc} to a {@literal String} to be used as a replacement of the SpEL in the query. The returned
- * value should normally be interpretable as a bind parameter by the underlying persistence mechanism. A typical
- * implementation is expected to look like <code>(prefix, name) -> prefix + name</code> or
- * <code>(prefix, name) -> "{" + name + "}"</code>
- */
- private final BiFunction<String, String, String> replacementSrc;
-
- /** */
- private SpelQueryContext(BiFunction<Integer, String, String> paramNameSrc,
- BiFunction<String, String, String> replacementSrc) {
- this.paramNameSrc = paramNameSrc;
- this.replacementSrc = replacementSrc;
- }
-
- /**
- * Of spel query context.
- *
- * @param parameterNameSource the parameter name source
- * @param replacementSource the replacement source
- * @return the spel query context
- */
- public static SpelQueryContext of(BiFunction<Integer, String, String> parameterNameSource,
- BiFunction<String, String, String> replacementSource) {
- return new SpelQueryContext(parameterNameSource, replacementSource);
- }
-
- /**
- * Parses the query for SpEL expressions using the pattern:
- *
- * <pre>
- * <prefix>#{<spel>}
- * </pre>
- * <p>
- * with prefix being the character ':' or '?'. Parsing honors quoted {@literal String}s enclosed in single or double
- * quotation marks.
- *
- * @param qry a query containing SpEL expressions in the format described above. Must not be {@literal null}.
- * @return A {@link SpelExtractor} which makes the query with SpEL expressions replaced by bind parameters and a map
- * from bind parameter to SpEL expression available. Guaranteed to be not {@literal null}.
- */
- public SpelExtractor parse(String qry) {
- return new SpelExtractor(qry);
- }
-
- /**
- * Createsa {@link EvaluatingSpelQueryContext} from the current one and the given {@link
- * EvaluationContextProvider}*.
- *
- * @param provider must not be {@literal null}.
- * @return Evaluating Spel QueryContext
- */
- public EvaluatingSpelQueryContext withEvaluationContextProvider(EvaluationContextProvider provider) {
- Assert.notNull(provider, "EvaluationContextProvider must not be null!");
-
- return new EvaluatingSpelQueryContext(provider, paramNameSrc, replacementSrc);
- }
-
- /**
- * An extension of {@link SpelQueryContext} that can create {@link SpelEvaluator} instances as it also knows about a
- * {@link EvaluationContextProvider}.
- *
- * @author Oliver Gierke
- */
- public static class EvaluatingSpelQueryContext extends SpelQueryContext {
- /** */
- private final EvaluationContextProvider evaluationContextProvider;
-
- /**
- * Creates a new {@link EvaluatingSpelQueryContext} for the given {@link EvaluationContextProvider}, parameter
- * name source and replacement source.
- *
- * @param evaluationCtxProvider must not be {@literal null}.
- * @param paramNameSrc must not be {@literal null}.
- * @param replacementSrc must not be {@literal null}.
- */
- private EvaluatingSpelQueryContext(EvaluationContextProvider evaluationCtxProvider,
- BiFunction<Integer, String, String> paramNameSrc, BiFunction<String, String, String> replacementSrc) {
- super(paramNameSrc, replacementSrc);
-
- evaluationContextProvider = evaluationCtxProvider;
- }
-
- /**
- * Parses the query for SpEL expressions using the pattern:
- *
- * <pre>
- * <prefix>#{<spel>}
- * </pre>
- * <p>
- * with prefix being the character ':' or '?'. Parsing honors quoted {@literal String}s enclosed in single or
- * double quotation marks.
- *
- * @param qry a query containing SpEL expressions in the format described above. Must not be {@literal
- * null}.
- * @param parameters a {@link Parameters} instance describing query method parameters
- * @return A {@link SpelEvaluator} which allows to evaluate the SpEL expressions. Will never be {@literal null}.
- */
- public SpelEvaluator parse(String qry, Parameters<?, ?> parameters) {
- return new SpelEvaluator(evaluationContextProvider, parameters, parse(qry));
- }
- }
-
- /**
- * Parses a query string, identifies the contained SpEL expressions, replaces them with bind parameters and offers a
- * {@link Map} from those bind parameters to the spel expression.
- * <p>
- * The parser detects quoted parts of the query string and does not detect SpEL expressions inside such quoted parts
- * of the query.
- *
- * @author Jens Schauder
- * @author Oliver Gierke
- */
- public class SpelExtractor {
- /** */
- private static final int PREFIX_GROUP_INDEX = 1;
-
- /** */
- private static final int EXPRESSION_GROUP_INDEX = 2;
-
- /** */
- private final String query;
-
- /** */
- private final Map<String, String> expressions;
-
- /** */
- private final QuotationMap quotations;
-
- /**
- * Creates a SpelExtractor from a query String.
- *
- * @param qry must not be {@literal null}.
- */
- SpelExtractor(String qry) {
- Assert.notNull(qry, "Query must not be null");
-
- Map<String, String> exps = new HashMap<>();
- Matcher matcher = SPEL_PATTERN.matcher(qry);
- StringBuilder resultQry = new StringBuilder();
- QuotationMap quotedAreas = new QuotationMap(qry);
-
- int expressionCounter = 0;
- int matchedUntil = 0;
-
- while (matcher.find()) {
- if (quotedAreas.isQuoted(matcher.start()))
- resultQry.append(qry, matchedUntil, matcher.end());
-
- else {
- String spelExpression = matcher.group(EXPRESSION_GROUP_INDEX);
- String prefix = matcher.group(PREFIX_GROUP_INDEX);
-
- String paramName = paramNameSrc.apply(expressionCounter, spelExpression);
- String replacement = replacementSrc.apply(prefix, paramName);
-
- resultQry.append(qry, matchedUntil, matcher.start());
- resultQry.append(replacement);
-
- exps.put(paramName, spelExpression);
- expressionCounter++;
- }
-
- matchedUntil = matcher.end();
- }
-
- resultQry.append(qry.substring(matchedUntil));
-
- expressions = Collections.unmodifiableMap(exps);
- query = resultQry.toString();
- quotations = quotedAreas;
- }
-
- /**
- * The query with all the SpEL expressions replaced with bind parameters.
- *
- * @return Guaranteed to be not {@literal null}.
- */
- public String getQueryString() {
- return query;
- }
-
- /**
- * Is quoted.
- *
- * @param idx the idx
- * @return the boolean
- */
- public boolean isQuoted(int idx) {
- return quotations.isQuoted(idx);
- }
-
- /**
- * Gets parameter.
- *
- * @param name the name
- * @return the parameter
- */
- public String getParameter(String name) {
- return expressions.get(name);
- }
-
- /**
- * A {@literal Map} from parameter name to SpEL expression.
- *
- * @return Guaranteed to be not {@literal null}.
- */
- Map<String, String> getParameterMap() {
- return expressions;
- }
-
- /**
- * Gets parameters.
- *
- * @return the parameters
- */
- Stream<Entry<String, String>> getParameters() {
- return expressions.entrySet().stream();
- }
- }
-
- /**
- * Value object to analyze a {@link String} to determine the parts of the {@link String} that are quoted and offers
- * an API to query that information.
- *
- * @author Jens Schauder
- * @author Oliver Gierke
- */
- static class QuotationMap {
- /** */
- private static final Collection<Character> QUOTING_CHARACTERS = Arrays.asList('"', '\'');
-
- /** */
- private final List<Range<Integer>> quotedRanges = new ArrayList<>();
-
- /**
- * Creates a new {@link QuotationMap} for the query.
- *
- * @param qry can be {@literal null}.
- */
- public QuotationMap(@Nullable String qry) {
- if (qry == null)
- return;
-
- Character inQuotation = null;
- int start = 0;
-
- for (int i = 0; i < qry.length(); i++) {
-
- char curChar = qry.charAt(i);
-
- if (QUOTING_CHARACTERS.contains(curChar)) {
-
- if (inQuotation == null) {
-
- inQuotation = curChar;
- start = i;
-
- }
- else if (curChar == inQuotation) {
-
- inQuotation = null;
-
- quotedRanges.add(Range.from(Bound.inclusive(start)).to(Bound.inclusive(i)));
- }
- }
- }
-
- if (inQuotation != null) {
- throw new IllegalArgumentException(
- String.format("The string <%s> starts a quoted range at %d, but never ends it.", qry, start));
- }
- }
-
- /**
- * Checks if a given index is within a quoted range.
- *
- * @param idx to check if it is part of a quoted range.
- * @return whether the query contains a quoted range at {@literal index}.
- */
- public boolean isQuoted(int idx) {
- return quotedRanges.stream().anyMatch(r -> r.contains(idx));
- }
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java
deleted file mode 100644
index 1b4b378..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import org.springframework.context.annotation.Condition;
-import org.springframework.context.annotation.ConditionContext;
-import org.springframework.core.type.AnnotatedTypeMetadata;
-
-/**
- * Always false condition. Tells spring context never load bean with such Condition.
- */
-public class ConditionFalse implements Condition {
- /** {@inheritDoc} */
- @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
- return false;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java
deleted file mode 100644
index b5280ee..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.config.BeanExpressionResolver;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-
-import static org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactory.getRepositoryConfiguration;
-
-/**
- * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
- * Ignite cluster.
- */
-public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
- /** Spring application expression resolver. */
- private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
-
- /** Repositories associated with Ignite proxy. */
- private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
-
- /** Spring application context. */
- private ApplicationContext ctx;
-
- /** Spring application bean expression context. */
- private BeanExpressionContext beanExpressionCtx;
-
- /**
- * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
- * @return {@link IgniteProxy} instance.
- */
- public IgniteProxy igniteProxy(Class<?> repoInterface) {
- return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
- }
-
- /** {@inheritDoc} */
- @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
- this.ctx = ctx;
-
- beanExpressionCtx = new BeanExpressionContext(
- new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
- null);
- }
-
- /** {@inheritDoc} */
- @Override public void destroy() throws Exception {
- Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
-
- Exception destroyE = null;
-
- for (IgniteProxy proxy : proxies) {
- if (proxy instanceof AutoCloseable) {
- try {
- ((AutoCloseable)proxy).close();
- }
- catch (Exception e) {
- if (destroyE == null)
- destroyE = e;
- else
- destroyE.addSuppressed(e);
- }
- }
- }
-
- if (destroyE != null)
- throw destroyE;
- }
-
- /**
- * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
- *
- * @param repoInterface {@link Class} instance of the repository interface.
- * @return Instance of {@link IgniteProxy} associated with specified repository.
- *
- * @see RepositoryConfig
- */
- private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
- RepositoryConfig repoCfg = getRepositoryConfiguration(repoInterface);
-
- return Stream.<BeanFinder>of(
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
- () -> ctx.getBean(Ignite.class),
- () -> ctx.getBean(IgniteClient.class),
- () -> ctx.getBean(IgniteConfiguration.class),
- () -> ctx.getBean(ClientConfiguration.class)
- ).map(BeanFinder::getBean)
- .filter(Objects::nonNull)
- .findFirst()
- .map(IgniteProxy::of)
- .orElseThrow(() -> {
- return new IllegalArgumentException("Invalid configuration for repository " +
- repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
- " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
- " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
- " ClientConfiguration or IgniteConfiguration bean to application context.");
- });
- }
-
- /**
- * Evaluates the SpEL expression.
- *
- * @param spelExpression SpEL expression
- * @return The result of evaluation of the SpEL expression.
- */
- private String evaluateExpression(String spelExpression) {
- return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
- }
-
- /**
- * Helper interface that wraps getBean method.
- */
- @FunctionalInterface
- private interface BeanFinder {
- /**
- * Get bean.
- * @return Bean or null if {@link BeansException} was thrown.
- */
- default Object getBean() {
- try {
- return get();
- } catch (BeansException ex) {
- return null;
- }
- }
-
- /**
- * Get bean.
- * @return Bean.
- * @throws BeansException If bean was not found.
- */
- Object get() throws BeansException;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java
deleted file mode 100644
index 2096277..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.support;
-
-import java.util.Optional;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata20.repository.query.IgniteQuery;
-import org.apache.ignite.springdata20.repository.query.IgniteQueryGenerator;
-import org.apache.ignite.springdata20.repository.query.IgniteRepositoryQuery;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.RepositoryInformation;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.core.support.AbstractEntityInformation;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * Crucial for spring-data functionality class. Create proxies for repositories.
- * <p>
- * Supports multiple Ignite Instances on same JVM.
- * <p>
- * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteRepositoryFactory extends RepositoryFactorySupport {
- /** Spring application expression resolver */
- private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
-
- /** Spring application bean expression context */
- private final BeanExpressionContext beanExpressionContext;
-
- /** Ignite cache proxy instance associated with the current repository. */
- private final IgniteCacheProxy<?, ?> cache;
-
- /** Ignite proxy instance associated with the current repository. */
- private final IgniteProxy ignite;
-
- /**
- * @param ctx Spring Application context.
- * @param repoInterface Repository interface.
- */
- public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
- ignite = ctx.getBean(IgniteProxy.class, repoInterface);
-
- beanExpressionContext = new BeanExpressionContext(
- new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
- null);
-
- RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
-
- String cacheName = evaluateExpression(cfg.cacheName());
-
- Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
- ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
- " annotation to map this repository to the underlying cache.");
-
- cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
-
- if (cache == null) {
- throw new IllegalArgumentException(
- "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
- + ". Please, add a cache configuration to ignite configuration"
- + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
- }
- }
-
- /** {@inheritDoc} */
- @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
- return new AbstractEntityInformation<T, ID>(domainClass) {
- /** {@inheritDoc} */
- @Override public ID getId(T entity) {
- return null;
- }
-
- /** {@inheritDoc} */
- @Override public Class<ID> getIdType() {
- return null;
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
- return IgniteRepositoryImpl.class;
- }
-
- /**
- * Evaluate the SpEL expression
- *
- * @param spelExpression SpEL expression
- * @return the result of execution of the SpEL expression
- */
- private String evaluateExpression(String spelExpression) {
- return (String)resolver.evaluate(spelExpression, beanExpressionContext);
- }
-
- /** {@inheritDoc} */
- @Override protected Object getTargetRepository(RepositoryInformation metadata) {
- return getTargetRepositoryViaReflection(metadata, ignite, cache);
- }
-
- /** {@inheritDoc} */
- @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
- EvaluationContextProvider evaluationContextProvider) {
- return Optional.of((mtd, metadata, factory, namedQueries) -> {
- final Query annotation = mtd.getAnnotation(Query.class);
- if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
- .dynamicQuery())) {
-
- String qryStr = annotation.value();
-
- boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
- .textQuery());
-
- IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
- !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
- annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
-
- if (key != QueryLookupStrategy.Key.CREATE) {
- return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
- annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
- evaluationContextProvider);
- }
- }
-
- if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
- throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
- + "a query string via org.apache.ignite.springdata20.repository"
- + ".config.Query annotation.");
- }
-
- return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
- cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
- });
- }
-
- /**
- * @param qry Query string.
- * @return {@code true} if query is SqlFieldsQuery.
- */
- public static boolean isFieldQuery(String qry) {
- String qryUpperCase = qry.toUpperCase();
-
- return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
- }
-
- /**
- * Evaluates if the query starts with a clause.<br>
- * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
- *
- * @param qryUpperCase Query string in upper case.
- * @return {@code true} if query is full SQL statement.
- */
- private static boolean isStatement(String qryUpperCase) {
- return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
- // update
- qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
- // delete
- qryUpperCase.matches("^\\s*DELETE\\b.*") ||
- // merge
- qryUpperCase.matches("^\\s*MERGE\\b.*") ||
- // insert
- qryUpperCase.matches("^\\s*INSERT\\b.*");
- }
-
- /**
- * @return Configuration of the specified repository.
- * @throws IllegalArgumentException If no configuration is specified.
- * @see RepositoryConfig
- */
- static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
- RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
-
- Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
- RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
-
- return cfg;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java
deleted file mode 100644
index 0ec1313..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-
-/**
- * Apache Ignite repository factory bean.
- * <p>
- * The {@link org.apache.ignite.springdata20.repository.config.RepositoryConfig} requires to define one of the
- * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
- * <ul/>
- *
- * @param <T> Repository type, {@link IgniteRepository}
- * @param <V> Domain object class.
- * @param <K> Domain object key, super expects {@link Serializable}.
- */
-public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
- extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
- /** */
- private ApplicationContext ctx;
-
- /**
- * @param repoInterface Repository interface.
- */
- protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
- super(repoInterface);
- }
-
- /** {@inheritDoc} */
- @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
- this.ctx = ctx;
- }
-
- /** {@inheritDoc} */
- @Override protected RepositoryFactorySupport createRepositoryFactory() {
- return new IgniteRepositoryFactory(ctx, getObjectType());
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java
deleted file mode 100644
index b3e449a..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.support;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.cache.Cache;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CachePeekMode;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.context.annotation.Conditional;
-
-/**
- * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
- * {@link IgniteRepositoryFactory}
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Conditional(ConditionFalse.class)
-public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
- /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
- private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
- " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
-
- /**
- * Ignite Cache bound to the repository
- */
- private final IgniteCacheProxy<K, V> cache;
-
- /**
- * Ignite instance bound to the repository
- */
- private final IgniteProxy ignite;
-
- /**
- * Repository constructor.
- *
- * @param ignite the ignite
- * @param cache Initialized cache instance.
- */
- public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
- this.cache = cache;
- this.ignite = ignite;
- }
-
- /** {@inheritDoc} */
- @Override public IgniteCache<K, V> cache() {
- if (cache instanceof IgniteNodeCacheProxy)
- return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
-
- throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
- }
-
- /** {@inheritDoc} */
- @Override public Ignite ignite() {
- if (ignite instanceof IgniteNodeProxy)
- return ((IgniteNodeProxy)ignite).delegate();
-
- throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> S save(K key, S entity) {
- cache.put(key, entity);
-
- return entity;
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
- cache.putAll(entities);
-
- return entities.values();
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
- if (expiryPlc != null)
- cache.withExpiryPolicy(expiryPlc).put(key, entity);
- else
- cache.put(key, entity);
- return entity;
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
- if (expiryPlc != null)
- cache.withExpiryPolicy(expiryPlc).putAll(entities);
- else
- cache.putAll(entities);
- return entities.values();
- }
-
- /**
- * Not implemented.
- */
- @Override public <S extends V> S save(S entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
- }
-
- /**
- * Not implemented.
- */
- @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
- throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public Optional<V> findById(K id) {
- return Optional.ofNullable(cache.get(id));
- }
-
- /** {@inheritDoc} */
- @Override public boolean existsById(K id) {
- return cache.containsKey(id);
- }
-
- /** {@inheritDoc} */
- @Override public Iterable<V> findAll() {
- final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
-
- return new Iterable<V>() {
- /** */
- @Override public Iterator<V> iterator() {
- return new Iterator<V>() {
- /** {@inheritDoc} */
- @Override public boolean hasNext() {
- return iter.hasNext();
- }
-
- /** {@inheritDoc} */
- @Override public V next() {
- return iter.next().getValue();
- }
-
- /** {@inheritDoc} */
- @Override public void remove() {
- iter.remove();
- }
- };
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override public Iterable<V> findAllById(Iterable<K> ids) {
- if (ids instanceof Set)
- return cache.getAll((Set<K>)ids).values();
-
- if (ids instanceof Collection)
- return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
-
- TreeSet<K> keys = new TreeSet<>();
-
- for (K id : ids)
- keys.add(id);
-
- return cache.getAll(keys).values();
- }
-
- /** {@inheritDoc} */
- @Override public long count() {
- return cache.size(CachePeekMode.PRIMARY);
- }
-
- /** {@inheritDoc} */
- @Override public void deleteById(K id) {
- cache.remove(id);
- }
-
- /** {@inheritDoc} */
- @Override public void delete(V entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAll(Iterable<? extends V> entities) {
- throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAllById(Iterable<K> ids) {
- if (ids instanceof Set) {
- cache.removeAll((Set<K>)ids);
- return;
- }
-
- if (ids instanceof Collection) {
- cache.removeAll(new HashSet<>((Collection<K>)ids));
- return;
- }
-
- TreeSet<K> keys = new TreeSet<>();
-
- for (K id : ids)
- keys.add(id);
-
- cache.removeAll(keys);
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAll() {
- cache.clear();
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java
deleted file mode 100644
index a9d4fd2..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains supporting files required by Spring Data framework.
- */
-package org.apache.ignite.springdata20.repository.support;
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
deleted file mode 100644
index ec2e7ca..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data operation with compound key when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCompoundKeyTest extends IgniteSpringDataCompoundKeyTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(CityRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override protected Ignite ignite() {
- return ctx.getBean("igniteServerNode", Ignite.class);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
deleted file mode 100644
index 226ee9b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- }
-
- /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
- @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
- GridTestUtils.assertThrows(log,
- () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
- "Query of type TextQuery is not supported by thin client. Check" +
- " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
- " method configuration or use Ignite node instance to connect to the Ignite cluster.");
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
deleted file mode 100644
index 27d3645..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data query operations when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataQueriesSelfTest extends IgniteSpringDataQueriesSelfTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- repo2 = ctx.getBean(PersonSecondRepository.class);
- repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
- for (int i = 0; i < CACHE_SIZE; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
deleted file mode 100644
index 3a65f29..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.Statement;
-import java.util.Optional;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.City;
-import org.apache.ignite.springdata.compoundkey.CityKey;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-
-/**
- * Test with using conpoud key in spring-data
- * */
-public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest {
- /** Application context */
- protected static AnnotationConfigApplicationContext ctx;
-
- /** City repository */
- protected static CityRepository repo;
-
- /** Cache name */
- private static final String CACHE_NAME = "City";
-
- /** Cities count */
- private static final int TOTAL_COUNT = 5;
-
- /** Count Afganistan cities */
- private static final int AFG_COUNT = 4;
-
- /** Kabul identifier */
- private static final int KABUL_ID = 1;
-
- /** Quandahar identifier */
- private static final int QUANDAHAR_ID = 2;
-
- /** Afganistan county code */
- private static final String AFG = "AFG";
-
- /** test city Kabul */
- private static final City KABUL = new City("Kabul", "Kabol", 1780000);
-
- /** test city Quandahar */
- private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
-
- /**
- * Performs context initialization before tests.
- */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
- ctx.register(CompoundKeyApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(CityRepository.class);
- }
-
- /**
- * Load data
- * */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- loadData();
-
- assertEquals(TOTAL_COUNT, repo.count());
- }
-
- /**
- * Performs context destroy after tests.
- */
- @Override protected void afterTestsStopped() {
- ctx.close();
- }
-
- /** load data*/
- public void loadData() throws Exception {
- Ignite ignite = ignite();
-
- if (ignite.cacheNames().contains(CACHE_NAME))
- ignite.destroyCache(CACHE_NAME);
-
- try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:" + CLI_CONN_PORT + '/')) {
- Statement st = conn.createStatement();
-
- st.execute("DROP TABLE IF EXISTS City");
- st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\"");
- st.execute("SET STREAMING ON;");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)");
- }
- }
-
- /** Test */
- @Test
- public void test() {
- assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
- assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
- assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
- }
-
- /** */
- protected Ignite ignite() {
- return ctx.getBean(Ignite.class);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
deleted file mode 100644
index 10d016d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
-import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE;
-
-/** Tests Spring Data repository cluster connection configurations. */
-public class IgniteSpringDataConnectionConfigurationTest extends GridCommonAbstractTest {
- /** */
- private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
- /** */
- private static final String CACHE_NAME = "PersonCache";
-
- /** */
- private static final int CLI_CONN_PORT = 10810;
-
- /** */
- private static final String CLI_NAME = "cli-node";
-
- /** */
- private static final String SRV_NAME = "srv-node";
-
- /** */
- private static final String LOCAL_HOST = "127.0.0.1";
-
- /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithIgniteConfiguration() {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
- assertClientNodeIsStopped();
- }
-
- /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithClientConfiguration() {
- checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
- }
-
- /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteInstanceParameter() {
- checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteClientInstanceParameter() {
- checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgnitClientConfigurationParameter() {
- checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteConfigurationParameter() {
- checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /**
- * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
- * used to access the Ignite cluster.
- */
- @Test
- public void testRepositoryWithExistingIgniteInstance() throws Exception {
- try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
- assertNotNull(Ignition.ignite(CLI_NAME));
- }
- }
-
- /** Tests repository configuration in case specified cache name is invalid. */
- @Test
- public void testRepositoryWithInvalidCacheNameConfiguration() {
- try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
- ctx.register(InvalidCacheNameApplication.class);
-
- assertThrowsAnyCause(log,
- () -> {
- ctx.refresh();
-
- return null;
- },
- IllegalArgumentException.class,
- "Cache 'invalidCache' not found for repository interface" +
- " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
- " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
- " org.apache.ignite.springdata20.repository.config.RepositoryConfig annotation.");
- }
-
- assertClientNodeIsStopped();
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- super.afterTest();
-
- grid(SRV_NAME).cache(CACHE_NAME).clear();
- }
-
- /** */
- private void assertClientNodeIsStopped() {
- assertFalse(Ignition.allGrids().stream().map(Ignite::name).anyMatch(CLI_NAME::equals));
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- startGrid(getIgniteConfiguration(SRV_NAME, false));
- }
-
- /**
- * Checks that repository created based on specified Spring application configuration is properly initialized and
- * got access to the Ignite cluster.
- */
- private void checkRepositoryConfiguration(
- Class<?> cfgCls,
- Class<? extends IgniteRepository<Object, Serializable>> repoCls
- ) {
- try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
- ctx.register(cfgCls);
- ctx.refresh();
-
- IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
-
- IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
-
- assertEquals(0, repo.count());
- assertEquals(0, cache.size());
-
- int key = 0;
-
- repo.save(key, "1");
-
- assertEquals(1, repo.count());
- assertNotNull(cache.get(key));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
- public static class InvalidCacheNameApplication {
- /** Ignite configuration bean. */
- @Bean
- public IgniteConfiguration igniteConfiguration() {
- return getIgniteConfiguration(CLI_NAME, true);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
- public static class IgniteConfigurationApplication {
- /** Ignite configuration bean. */
- @Bean
- public IgniteConfiguration igniteConfiguration() {
- return getIgniteConfiguration(CLI_NAME, true);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link ClientConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
- public static class ClientConfigurationApplication {
- /** Ignite client configuration bean. */
- @Bean
- public ClientConfiguration clientConfiguration() {
- return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if Ignite bean name was not provided
- * through {@link RepositoryConfig#igniteInstance()} ()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteBeanApplication {
- /** Ignite bean. */
- @Bean
- public Ignite someIgnite() {
- return Ignition.start(getIgniteConfiguration("test", false));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
- * through {@link RepositoryConfig#igniteInstance()} ()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteClientBeanApplication {
- /** Ignite client bean. */
- @Bean
- public IgniteClient someIgnite() {
- return Ignition.startClient(new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
- * through {@link RepositoryConfig#igniteCfg()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteClientConfigurationBeanApplication {
- /** Ignite client configuration bean. */
- @Bean
- public ClientConfiguration someCfg() {
- return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
- * through {@link RepositoryConfig#igniteCfg()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteConfigurationBeanApplication {
- /** Ignite client configuration bean. */
- @Bean
- public IgniteConfiguration someCfg() {
- return getIgniteConfiguration("test", false);
- }
- }
-
- /** Repository for testing configuration approach through default ignite beans. */
- @RepositoryConfig(cacheName = "PersonCache")
- public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
- @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
- public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
- @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
- public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
- @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
- public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** */
- private static IgniteConfiguration getIgniteConfiguration(String name, boolean clientMode) {
- return new IgniteConfiguration()
- .setIgniteInstanceName(name)
- .setClientMode(clientMode)
- .setLocalHost(LOCAL_HOST)
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER))
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
- .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME));
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
deleted file mode 100644
index 5841f41..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.util.Collection;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonExpressionRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * Test with using repository which is configured by Spring EL
- */
-public class IgniteSpringDataCrudSelfExpressionTest extends GridCommonAbstractTest {
- /** Number of entries to store */
- private static final int CACHE_SIZE = 1000;
-
- /** Repository. */
- private static PersonExpressionRepository repo;
-
- /** Context. */
- private static AnnotationConfigApplicationContext ctx;
-
- /** */
- @Rule
- public final ExpectedException expected = ExpectedException.none();
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
- ctx.register(ApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(PersonExpressionRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- fillInRepository();
-
- assertEquals(CACHE_SIZE, repo.count());
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- repo.deleteAll();
-
- assertEquals(0, repo.count());
-
- super.afterTest();
- }
-
- /** */
- private void fillInRepository() {
- for (int i = 0; i < CACHE_SIZE - 5; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
-
- repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTestsStopped() {
- ctx.close();
- }
-
- /**
- * Tests put & get operations.
- */
- @Test
- public void testPutGet() {
- Person person = new Person("some_name", "some_surname");
-
- int id = CACHE_SIZE + 1;
-
- assertEquals(person, repo.save(id, person));
-
- assertTrue(repo.existsById(id));
-
- assertEquals(person, repo.findById(id).get());
-
- expected.expect(UnsupportedOperationException.class);
- expected.expectMessage("Use IgniteRepository.save(key,value) method instead.");
- repo.save(person);
- }
-
- /**
- * Tests SpEL expression.
- */
- @Test
- public void testCacheCount() {
- Ignite ignite = ctx.getBean("igniteInstance", Ignite.class);
-
- Collection<String> cacheNames = ignite.cacheNames();
-
- assertFalse("The SpEL \"#{cacheNames.personCacheName}\" isn't processed!",
- cacheNames.contains("#{cacheNames.personCacheName}"));
-
- assertTrue("Cache \"PersonCache\" isn't found!",
- cacheNames.contains("PersonCache"));
- }
-
- /** */
- @Test
- public void testCacheCountTWO() {
- Ignite ignite = ctx.getBean("igniteInstanceTWO", Ignite.class);
-
- Collection<String> cacheNames = ignite.cacheNames();
-
- assertFalse("The SpEL \"#{cacheNames.personCacheName}\" isn't processed!",
- cacheNames.contains("#{cacheNames.personCacheName}"));
-
- assertTrue("Cache \"PersonCache\" isn't found!",
- cacheNames.contains("PersonCache"));
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
deleted file mode 100644
index a543044..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.TreeSet;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.FullNameProjection;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * CRUD tests.
- */
-public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
- /** Repository. */
- protected static PersonRepository repo;
-
- /** Context. */
- protected static AnnotationConfigApplicationContext ctx;
-
- /** Number of entries to store */
- private static int CACHE_SIZE = 1000;
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(ApplicationConfiguration.class);
-
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- fillInRepository();
-
- assertEquals(CACHE_SIZE, repo.count());
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- repo.deleteAll();
-
- assertEquals(0, repo.count());
-
- super.afterTest();
- }
-
- /** */
- private void fillInRepository() {
- for (int i = 0; i < CACHE_SIZE - 5; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
-
- repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTestsStopped() throws Exception {
- ctx.destroy();
- }
-
- /** */
- @Test
- public void testPutGet() {
- Person person = new Person("some_name", "some_surname");
-
- int id = CACHE_SIZE + 1;
-
- assertEquals(person, repo.save(id, person));
-
- assertTrue(repo.existsById(id));
-
- assertEquals(person, repo.findById(id).get());
-
- try {
- repo.save(person);
-
- fail("Managed to save a Person without ID");
- }
- catch (UnsupportedOperationException e) {
- //excepted
- }
- }
-
- /** */
- @Test
- public void testPutAllGetAll() {
- LinkedHashMap<Integer, Person> map = new LinkedHashMap<>();
-
- for (int i = CACHE_SIZE; i < CACHE_SIZE + 50; i++)
- map.put(i, new Person("some_name" + i, "some_surname" + i));
-
- Iterator<Person> persons = repo.save(map).iterator();
-
- assertEquals(CACHE_SIZE + 50, repo.count());
-
- Iterator<Person> origPersons = map.values().iterator();
-
- while (persons.hasNext())
- assertEquals(origPersons.next(), persons.next());
-
- try {
- repo.saveAll(map.values());
-
- fail("Managed to save a list of Persons with ids");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
-
- persons = repo.findAllById(map.keySet()).iterator();
-
- int counter = 0;
-
- while (persons.hasNext()) {
- persons.next();
- counter++;
- }
-
- assertEquals(map.size(), counter);
- }
-
- /** */
- @Test
- public void testGetAll() {
- assertEquals(CACHE_SIZE, repo.count());
-
- Iterator<Person> persons = repo.findAll().iterator();
-
- int counter = 0;
-
- while (persons.hasNext()) {
- persons.next();
- counter++;
- }
-
- assertEquals(repo.count(), counter);
- }
-
- /** */
- @Test
- public void testDelete() {
- assertEquals(CACHE_SIZE, repo.count());
-
- repo.deleteById(0);
-
- assertEquals(CACHE_SIZE - 1, repo.count());
- assertEquals(Optional.empty(),repo.findById(0));
-
- try {
- repo.delete(new Person("", ""));
-
- fail("Managed to delete a Person without id");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /** */
- @Test
- public void testDeleteSet() {
- assertEquals(CACHE_SIZE, repo.count());
-
- TreeSet<Integer> ids = new TreeSet<>();
-
- for (int i = 0; i < CACHE_SIZE / 2; i++)
- ids.add(i);
-
- repo.deleteAllById(ids);
-
- assertEquals(CACHE_SIZE / 2, repo.count());
-
- try {
- ArrayList<Person> persons = new ArrayList<>();
-
- for (int i = 0; i < 3; i++)
- persons.add(new Person(String.valueOf(i), String.valueOf(i)));
-
- repo.deleteAll(persons);
-
- fail("Managed to delete Persons without ids");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /** */
- @Test
- public void testDeleteAll() {
- assertEquals(CACHE_SIZE, repo.count());
-
- repo.deleteAll();
-
- assertEquals(0, repo.count());
- }
-
- /**
- * Delete existing record.
- */
- @Test
- public void testDeleteByFirstName() {
- assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
-
- long cnt = repo.deleteByFirstName("uniquePerson");
-
- assertEquals(1, cnt);
- }
-
- /**
- * Delete NON existing record.
- */
- @Test
- public void testDeleteExpression() {
- long cnt = repo.deleteByFirstName("880");
-
- assertEquals(0, cnt);
- }
-
- /**
- * Delete Multiple records due to where.
- */
- @Test
- public void testDeleteExpressionMultiple() {
- long count = repo.countByFirstName("nonUniquePerson");
- long cnt = repo.deleteByFirstName("nonUniquePerson");
-
- assertEquals(cnt, count);
- }
-
- /**
- * Remove should do the same than Delete.
- */
- @Test
- public void testRemoveExpression() {
- repo.removeByFirstName("person3f");
-
- long count = repo.count();
- assertEquals(CACHE_SIZE - 1, count);
- }
-
- /**
- * Delete unique record using lower case key word.
- */
- @Test
- public void testDeleteQuery() {
- repo.deleteBySecondNameLowerCase("uniqueLastName");
-
- long countAfter = repo.count();
- assertEquals(CACHE_SIZE - 1, countAfter);
- }
-
- /**
- * Try to delete with a wrong @Query.
- */
- @Test
- public void testWrongDeleteQuery() {
- long countBefore = repo.countByFirstNameLike("person3f");
-
- try {
- repo.deleteWrongByFirstNameQuery("person3f");
- }
- catch (Exception e) {
- //expected
- }
-
- long countAfter = repo.countByFirstNameLike("person3f");
- assertEquals(countBefore, countAfter);
- }
-
- /**
- * Update with a @Query a record.
- */
- @Test
- public void testUpdateQueryMixedCase() {
- final String newSecondName = "updatedUniqueSecondName";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<Person> person = repo.findByFirstName("uniquePerson");
- assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
- }
-
- /**
- * Update with a @Query a record
- */
- @Test
- public void testUpdateQueryMixedCaseProjection() {
- final String newSecondName = "updatedUniqueSecondName1";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-
- List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
- assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
- assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
-
- FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
- assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
- final String newSecondName = "updatedUniqueSecondName3";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
- final String newSecondName = "updatedUniqueSecondName4";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
- final String newSecondName = "updatedUniqueSecondName5";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
- final String newSecondName = "updatedUniqueSecondName6";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
- assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
- }
-
- /**
- * Update with a wrong @Query
- */
- @Test
- public void testWrongUpdateQuery() {
- final String newSecondName = "updatedUniqueSecondName";
- int rowsUpdated = 0;
-
- try {
- rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
- }
- catch (Exception ignored) {
- //expected
- }
-
- assertEquals(0, rowsUpdated);
-
- List<Person> person = repo.findByFirstName("uniquePerson");
- assertEquals(person.get(0).getSecondName(), "uniqueLastName");
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
deleted file mode 100644
index 0445e0d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.cache.Cache;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.Sort;
-
-/**
- *
- */
-public class IgniteSpringDataQueriesSelfTest extends GridCommonAbstractTest {
- /** Repository. */
- protected static PersonRepository repo;
-
- /** Repository 2. */
- protected static PersonSecondRepository repo2;
-
- /**
- * Repository Ignite Instance cluster TWO.
- */
- protected static PersonRepositoryOtherIgniteInstance repoTWO;
-
- /** Context. */
- protected static AnnotationConfigApplicationContext ctx;
-
- /**
- * Number of entries to store
- */
- protected static int CACHE_SIZE = 1000;
-
- /**
- * Performs context initialization before tests.
- */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(ApplicationConfiguration.class);
-
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- repo2 = ctx.getBean(PersonSecondRepository.class);
- // repository on another ignite instance (and another cluster)
- repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
- for (int i = 0; i < CACHE_SIZE; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
- }
-
- /**
- * Performs context destroy after tests.
- */
- @Override protected void afterTestsStopped() throws Exception {
- ctx.destroy();
- }
-
- /** */
- @Test
- public void testExplicitQuery() {
- List<Person> persons = repo.simpleQuery("person4a");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("person4a", person.getFirstName());
- }
-
- /** */
- @Test
- public void testExplicitQueryTWO() {
- List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("TWOperson4a", person.getFirstName());
- }
-
- /** */
- @Test
- public void testEqualsPart() {
- List<Person> persons = repo.findByFirstName("person4e");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("person4e", person.getFirstName());
- }
-
- /** */
- @Test
- public void testEqualsPartTWO() {
- List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("TWOperson4e", person.getFirstName());
- }
-
- /** */
- @Test
- public void testContainingPart() {
- List<Person> persons = repo.findByFirstNameContaining("person4");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertTrue(person.getFirstName().startsWith("person4"));
- }
-
- /** */
- @Test
- public void testContainingPartTWO() {
- List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertTrue(person.getFirstName().startsWith("TWOperson4"));
- }
-
- /** */
- @Test
- public void testTopPart() {
- Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
-
- Iterator<Person> iter = top.iterator();
-
- Person person = iter.next();
-
- assertFalse(iter.hasNext());
-
- assertTrue(person.getFirstName().startsWith("person4"));
- }
-
- /** */
- @Test
- public void testTopPartTWO() {
- Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
-
- Iterator<Person> iter = top.iterator();
-
- Person person = iter.next();
-
- assertFalse(iter.hasNext());
-
- assertTrue(person.getFirstName().startsWith("TWOperson4"));
- }
-
- /** */
- @Test
- public void testLikeAndLimit() {
- Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
-
- int cnt = 0;
-
- for (Person next : like) {
- assertTrue(next.getFirstName().contains("person"));
-
- cnt++;
- }
-
- assertEquals(10, cnt);
- }
-
- /** */
- @Test
- public void testLikeAndLimitTWO() {
- Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
-
- int cnt = 0;
-
- for (Person next : like) {
- assertTrue(next.getFirstName().contains("TWOperson"));
-
- cnt++;
- }
-
- assertEquals(10, cnt);
- }
-
- /** */
- @Test
- public void testCount() {
- int cnt = repo.countByFirstNameLike("person");
-
- assertEquals(1000, cnt);
- }
-
- /** */
- @Test
- public void testCountTWO() {
- int cnt = repoTWO.countByFirstNameLike("TWOperson");
-
- assertEquals(1000, cnt);
- }
-
- /** */
- @Test
- public void testCount2() {
- int cnt = repo.countByFirstNameLike("person4");
-
- assertTrue(cnt < 1000);
- }
-
- /** */
- @Test
- public void testCount2TWO() {
- int cnt = repoTWO.countByFirstNameLike("TWOperson4");
-
- assertTrue(cnt < 1000);
- }
-
- /** */
- @Test
- public void testPageable() {
- PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, "firstName");
-
- HashSet<String> firstNames = new HashSet<>();
-
- List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", pageable);
-
- assertEquals(5, pageable1.size());
-
- for (Person person : pageable1) {
- firstNames.add(person.getFirstName());
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
- }
-
- List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", pageable.next());
-
- assertEquals(5, pageable2.size());
-
- for (Person person : pageable2) {
- firstNames.add(person.getFirstName());
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
- }
-
- assertEquals(10, firstNames.size());
- }
-
- /** */
- @Test
- public void testAndAndOr() {
- int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
-
- int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", "lastName1");
-
- assertTrue(cntAnd <= cntOr);
- }
-
- /** */
- @Test
- public void testQueryWithSort() {
- List<Person> persons = repo.queryWithSort("^[a-z]+$", new Sort(Sort.Direction.DESC, "secondName"));
-
- Person previous = persons.get(0);
-
- for (Person person : persons) {
- assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
- previous = person;
- }
- }
-
- /** */
- @Test
- public void testQueryWithPaging() {
- List<Person> persons = repo.queryWithPageable("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
-
- assertEquals(7, persons.size());
-
- Person previous = persons.get(0);
-
- for (Person person : persons) {
- assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
- previous = person;
- }
- }
-
- /** */
- @Test
- public void testQueryFields() {
- List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
-
- assertEquals(7, persons.size());
- }
-
- /** */
- @Test
- public void testFindCacheEntries() {
- List<Cache.Entry<Integer, Person>> cacheEntries = repo.findBySecondNameLike("stName1");
-
- assertFalse(cacheEntries.isEmpty());
-
- for (Cache.Entry<Integer, Person> entry : cacheEntries)
- assertTrue(entry.getValue().getSecondName().contains("stName1"));
- }
-
- /** */
- @Test
- public void testFindOneCacheEntry() {
- Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
-
- assertNotNull(cacheEntry);
-
- assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
- }
-
- /** */
- @Test
- public void testFindOneValue() {
- PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
-
- assertNotNull(person);
-
- assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
- }
-
- /** */
- @Test
- public void testSelectSeveralFields() {
- List<List> lists = repo.selectSeveralField("^[a-z]+$", new PageRequest(2, 6));
-
- assertEquals(6, lists.size());
-
- for (List list : lists) {
- assertEquals(2, list.size());
-
- assertTrue(list.get(0) instanceof Integer);
- }
- }
-
- /** */
- @Test
- public void testCountQuery() {
- int cnt = repo.countQuery(".*");
-
- assertEquals(256, cnt);
- }
-
- /** */
- @Test
- public void testSliceOfCacheEntries() {
- Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
-
- assertEquals(4, slice.getSize());
-
- for (Cache.Entry<Integer, Person> entry : slice)
- assertFalse("lastName18".equals(entry.getValue().getSecondName()));
- }
-
- /** */
- @Test
- public void testSliceOfLists() {
- Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new PageRequest(0, 3));
-
- assertEquals(3, lists.getSize());
-
- for (List list : lists) {
- assertEquals(2, list.size());
-
- assertTrue(list.get(0) instanceof Integer);
- }
- }
-
- /** Tests conversion of SQL select query result to domain entity objects. */
- @Test
- public void testRowToEntityConversion() {
- Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
-
- Set<Person> exp = new HashSet<>();
-
- repo.findAll().forEach(exp::add);
-
- assertEquals(exp, res);
- }
-
- /**
- * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
- * of domain entity class.
- */
- @Test
- public void testIncompleteRowToEntityConversion() {
- Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
-
- Set<Person> exp = new HashSet<>();
-
- repo.findAll().forEach(p -> {
- p.setSecondName(null);
-
- exp.add(p);
- });
-
- assertEquals(exp, res);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
deleted file mode 100644
index e86a575..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.Objects;
-
-/**
- * Value-class
- * */
-public class City {
- /** City name */
- private String name;
-
- /** City district */
- private String district;
-
- /** City population */
- private int population;
-
- /**
- * @param name city name
- * @param district city district
- * @param population city population
- * */
- public City(String name, String district, int population) {
- this.name = name;
- this.district = district;
- this.population = population;
- }
-
- /**
- * @return city name
- * */
- public String getName() {
- return name;
- }
-
- /**
- * @param name city name
- * */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @return city district
- * */
- public String getDistrict() {
- return district;
- }
-
- /**
- * @param district city district
- * */
- public void setDistrict(String district) {
- this.district = district;
- }
-
- /**
- * @return city population
- * */
- public int getPopulation() {
- return population;
- }
-
- /**
- * @param population city population
- * */
- public void setPopulation(int population) {
- this.population = population;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return name + " | " + district + " | " + population;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- City city = (City)o;
-
- return
- Objects.equals(this.name, city.name) &&
- Objects.equals(this.district, city.district) &&
- this.population == city.population;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(name, district, population);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
deleted file mode 100644
index 8a5dba0..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.io.Serializable;
-import java.util.Objects;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/** Compound key for city class */
-public class CityKey implements Serializable {
- /** city identifier */
- private int ID;
-
- /** affinity key countrycode */
- @AffinityKeyMapped
- private String COUNTRYCODE;
-
- /**
- * @param id city identifier
- * @param countryCode city countrycode
- * */
- public CityKey(int id, String countryCode) {
- this.ID = id;
- this.COUNTRYCODE = countryCode;
- }
-
- /**
- * @return city id
- * */
- public int getId() {
- return ID;
- }
-
- /**
- * @return countrycode
- * */
- public String getCountryCode() {
- return COUNTRYCODE;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
- CityKey key = (CityKey)o;
- return ID == key.ID &&
- COUNTRYCODE.equals(key.COUNTRYCODE);
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(ID, COUNTRYCODE);
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return ID + " | " + COUNTRYCODE;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
deleted file mode 100644
index d9adee3..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.stereotype.Repository;
-
-/** City repository */
-@Repository
-@RepositoryConfig(cacheName = "City", autoCreateCache = true)
-public interface CityRepository extends IgniteRepository<City, CityKey> {
- /**
- * Find city by id
- * @param id city identifier
- * @return city
- * */
- public City findById(int id);
-
- /**
- * Find all cities by coutrycode
- * @param cc coutrycode
- * @return list of cache enrties CityKey -> City
- * */
- public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
deleted file mode 100644
index 03c05cd..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Spring application configuration
- * */
-@Configuration
-@EnableIgniteRepositories
-public class CompoundKeyApplicationConfiguration {
- /** */
- public static final int CLI_CONN_PORT = 10810;
-
- /**
- * Ignite instance bean
- * */
- @Bean
- public Ignite igniteInstance() {
- return Ignition.start(new IgniteConfiguration()
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT)));
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
deleted file mode 100644
index bce3340..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.repository.query.spi.EvaluationContextExtension;
-
-/** */
-@Configuration
-@EnableIgniteRepositories
-public class ApplicationConfiguration {
- /** */
- public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
-
- /** */
- public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
-
- /**
- * The bean with cache names
- */
- @Bean
- public CacheNamesBean cacheNames() {
- CacheNamesBean bean = new CacheNamesBean();
-
- bean.setPersonCacheName("PersonCache");
-
- return bean;
- }
-
- /** */
- @Bean
- public EvaluationContextExtension sampleSpELExtension() {
- return new SampleEvaluationContextExtension();
- }
-
- /** */
- @Bean(value = "sampleExtensionBean")
- public SamplePassParamExtension sampleExtensionBean() {
- return new SamplePassParamExtension();
- }
-
- /**
- * Ignite instance bean - no instance name provided on RepositoryConfig
- */
- @Bean
- public Ignite igniteInstance() {
- IgniteConfiguration cfg = new IgniteConfiguration();
-
- cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
-
- CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
- ccfg.setIndexedTypes(Integer.class, Person.class);
-
- cfg.setCacheConfiguration(ccfg);
-
- TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
- spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
- cfg.setDiscoverySpi(spi);
-
- return Ignition.start(cfg);
- }
-
- /**
- * Ignite instance bean with not default name
- */
- @Bean
- public Ignite igniteInstanceTWO() {
- IgniteConfiguration cfg = new IgniteConfiguration();
-
- cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
-
- CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
- ccfg.setIndexedTypes(Integer.class, Person.class);
-
- cfg.setCacheConfiguration(ccfg);
-
- TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
- spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
- cfg.setDiscoverySpi(spi);
-
- return Ignition.start(cfg);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
deleted file mode 100644
index 7b69075..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.repository.query.spi.EvaluationContextExtension;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
-
-/** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
-@Configuration
-@EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
-public class IgniteClientApplicationConfiguration {
- /** Test cache name. */
- public static final String CACHE_NAME = "PersonCache";
-
- /** */
- @Bean
- public CacheNamesBean cacheNames() {
- CacheNamesBean bean = new CacheNamesBean();
-
- bean.setPersonCacheName(CACHE_NAME);
-
- return bean;
- }
-
- /** */
- @Bean
- public EvaluationContextExtension sampleSpELExtension() {
- return new SampleEvaluationContextExtension();
- }
-
- /** */
- @Bean(value = "sampleExtensionBean")
- public SamplePassParamExtension sampleExtensionBean() {
- return new SamplePassParamExtension();
- }
-
- /** */
- @Bean
- public Ignite igniteServerNode() {
- return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
- }
-
- /** */
- @Bean
- public Ignite igniteSecondServerNode() {
- return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
- }
-
- /** Ignite client instance bean with default name. */
- @Bean
- public IgniteClient igniteInstance() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
- .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
- }
-
- /** Ignite client instance bean with non-default name. */
- @Bean
- public IgniteClient igniteInstanceTWO() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
- }
-
- /** */
- private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
- return new IgniteConfiguration()
- .setIgniteInstanceName(igniteInstanceName)
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
- .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
- .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
deleted file mode 100644
index 62c3054..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Date;
-import java.util.Objects;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * DTO class.
- */
-public class Person {
- /** First name. */
- @QuerySqlField(index = true)
- @QueryTextField
- private String firstName;
-
- /** Second name. */
- @QuerySqlField(index = true)
- private String secondName;
-
- /** Birthday. */
- @QuerySqlField
- private Date birthday;
-
- /**
- * @param firstName First name.
- * @param secondName Second name.
- */
- public Person(String firstName, String secondName) {
- this.firstName = firstName;
- this.secondName = secondName;
- birthday = new Date();
- }
-
- /**
- * @return First name.
- */
- public String getFirstName() {
- return firstName;
- }
-
- /**
- * @param firstName First name.
- */
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
-
- /**
- * @return Second name.
- */
- public String getSecondName() {
- return secondName;
- }
-
- /**
- * @param secondName Second name.
- */
- public void setSecondName(String secondName) {
- this.secondName = secondName;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Person{" +
- "firstName='" + firstName + '\'' +
- ", secondName='" + secondName + '\'' +
- ", birthday='" + birthday + '\'' +
- '}';
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- Person person = (Person)o;
-
- return Objects.equals(firstName, person.firstName) &&
- Objects.equals(secondName, person.secondName) &&
- Objects.equals(birthday, person.birthday);
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(firstName, secondName, birthday);
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
deleted file mode 100644
index 2537c57..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.io.Serializable;
-
-/**
- * Compound key.
- */
-public class PersonKey implements Serializable {
- /** */
- private int id1;
-
- /** */
- private int id2;
-
- /**
- * @param id1 ID1.
- * @param id2 ID2.
- */
- public PersonKey(int id1, int id2) {
- this.id1 = id1;
- this.id2 = id2;
- }
-
- /**
- * @return ID1
- */
- public int getId1() {
- return id1;
- }
-
- /**
- * @return ID1
- */
- public int getId2() {
- return id1;
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
deleted file mode 100644
index 7ea699b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Integer> {
- /** */
- public List<Person> findByFirstName(String val);
-
- /** */
- @Query("firstName = ?")
- public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
- /** */
- @Query("firstName = :firstname")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- /** */
- @Query("firstName = :firstname")
- public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
- /** */
- @Query("firstName = :firstname")
- public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
- /** */
- @Query("firstName = ?#{[1]}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
- /** */
- @Query(textQuery = true, value = "#{#firstname}", limit = 2)
- public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
- @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
- /** */
- public List<Person> findByFirstNameContaining(String val);
-
- /** */
- public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
- /** */
- public Collection<Person> findTopByFirstNameContaining(String val);
-
- /** */
- public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
- /** */
- public int countByFirstName(String val);
-
- /** */
- public int countByFirstNameLike(String val);
-
- /** */
- public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
- /** */
- public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
- /** */
- public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
- /** */
- public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
- /** */
- public PersonProjection findTopBySecondNameStartingWith(String val);
-
- /** */
- @Query("firstName = ?")
- public List<Person> simpleQuery(String val);
-
- /** */
- @Query("firstName REGEXP ?")
- public List<Person> queryWithSort(String val, Sort sort);
-
- /** */
- @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
- public List<Person> queryWithPageable(String val, Pageable pageable);
-
- /** */
- @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
- public List<String> selectField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
- public List<List> selectSeveralField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
- public int countQuery(String val);
-
- /** Top 3 query */
- public List<Person> findTop3ByFirstName(String val);
-
- /** Delete query */
- public long deleteByFirstName(String firstName);
-
- /** Remove Query */
- public List<Person> removeByFirstName(String firstName);
-
- /** Delete using @Query with keyword in lower-case */
- @Query("delete FROM Person WHERE secondName = ?")
- public void deleteBySecondNameLowerCase(String secondName);
-
- /** Delete using @Query but with errors on the query */
- @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public void deleteWrongByFirstNameQuery(String firstName);
-
- /** Update using @Query with keyword in mixed-case */
- @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
- public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
- /** Update using @Query but with errors on the query */
- @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public int setWrongFixedSecondName(String secondName, String firstName);
-
- /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
- @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
- public List<Person> queryWithRowToEntityConversion();
-
- /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
- @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
- public List<Person> queryWithIncompleteRowToEntityConversion();
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
deleted file mode 100644
index ac6231b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- *
- */
-@RepositoryConfig(igniteInstance = "igniteInstanceTWO", cacheName = "PersonCache")
-public interface PersonRepositoryOtherIgniteInstance extends IgniteRepository<Person, Integer> {
- /** */
- public List<Person> findByFirstName(String val);
-
- /** */
- @Query("firstName = ?")
- public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
- /** */
- @Query("firstName = :firstname")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- /** */
- @Query("firstName = ?#{[1]}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
- /** */
- @Query(textQuery = true, value = "#{#firstname}", limit = 2)
- public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
- @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
- /** */
- public List<Person> findByFirstNameContaining(String val);
-
- /** */
- public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
- /** */
- public Collection<Person> findTopByFirstNameContaining(String val);
-
- /** */
- public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
- /** */
- public int countByFirstName(String val);
-
- /** */
- public int countByFirstNameLike(String val);
-
- /** */
- public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
- /** */
- public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
- /** */
- public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
- /** */
- public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
- /** */
- public PersonProjection findTopBySecondNameStartingWith(String val);
-
- /** */
- @Query("firstName = ?")
- public List<Person> simpleQuery(String val);
-
- /** */
- @Query("firstName REGEXP ?")
- public List<Person> queryWithSort(String val, Sort sort);
-
- /** */
- @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
- public List<Person> queryWithPageable(String val, Pageable pageable);
-
- /** */
- @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
- public List<String> selectField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
- public List<List> selectSeveralField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
- public int countQuery(String val);
-
- /** Top 3 query */
- public List<Person> findTop3ByFirstName(String val);
-
- /** Delete query */
- public long deleteByFirstName(String firstName);
-
- /** Remove Query */
- public List<Person> removeByFirstName(String firstName);
-
- /** Delete using @Query with keyword in lower-case */
- @Query("delete FROM Person WHERE secondName = ?")
- public void deleteBySecondNameLowerCase(String secondName);
-
- /** Delete using @Query but with errors on the query */
- @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public void deleteWrongByFirstNameQuery(String firstName);
-
- /** Update using @Query with keyword in mixed-case */
- @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
- public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
- /** Update using @Query but with errors on the query */
- @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public int setWrongFixedSecondName(String secondName, String firstName);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
deleted file mode 100644
index bf77597..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
-public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
deleted file mode 100644
index 2bc713c..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.AbstractPageRequest;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
- /** */
- public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String val, PageRequest pageReq);
-
- /** */
- @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
- public Slice<List> querySliceOfList(String val, AbstractPageRequest pageReq);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
deleted file mode 100644
index 0fa535d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport;
-
-/**
- * Sample EvaluationContext Extension for Spring Data 2.0
- * <p>
- * Use SpEl expressions into your {@code @Query} definitions.
- * <p>
- * First, you need to register your extension into your spring data configuration. Sample:
- * <pre>
- * {@code @Configuration}
- * {@code @EnableIgniteRepositories}(basePackages = ... )
- * public class MyIgniteRepoConfig {
- * ...
- * {@code @Bean}
- * public EvaluationContextExtension sampleSpELExtension() {
- * return new SampleEvaluationContextExtension();
- * }
- * ...
- * }
- * </pre>
- *
- * <p>
- * Sample of usage into your {@code @Query} definitions:
- * <pre>
- * {@code @RepositoryConfig}(cacheName = "users")
- * public interface UserRepository
- * extends IgniteRepository<User, UUID>{
- * [...]
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?#{sampleExtension.transformParam(#email)}")
- * User searchUserByEmail(@Param("email") String email);
- *
- * [...]
- * }
- * </pre>
- * <p>
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public class SampleEvaluationContextExtension extends EvaluationContextExtensionSupport {
- /** */
- private static final SamplePassParamExtension SAMPLE_PASS_PARAM_EXTENSION_INSTANCE = new SamplePassParamExtension();
-
- /** */
- private static final Map<String, Object> properties = new HashMap<>();
-
- /** */
- private static final String SAMPLE_EXTENSION_SPEL_VAR = "sampleExtension";
-
- static {
- properties.put(SAMPLE_EXTENSION_SPEL_VAR, SAMPLE_PASS_PARAM_EXTENSION_INSTANCE);
- }
-
- /** */
- @Override public String getExtensionId() {
- return "HK-SAMPLE-PASS-PARAM-EXTENSION";
- }
-
- /** */
- @Override public Map<String, Object> getProperties() {
- return properties;
- }
-
- /** */
- public static class SamplePassParamExtension {
- // just return same param
- public Object transformParam(Object param) {
- return param;
- }
- }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java
deleted file mode 100644
index 88879e2..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.testsuites;
-
-import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Ignite Spring Data 2.0 test suite.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- IgniteSpringDataCrudSelfTest.class,
- IgniteSpringDataQueriesSelfTest.class,
- IgniteSpringDataCrudSelfExpressionTest.class,
- IgniteSpringDataCompoundKeyTest.class,
- IgniteSpringDataConnectionConfigurationTest.class,
- IgniteClientSpringDataCrudSelfTest.class,
- IgniteClientSpringDataQueriesSelfTest.class,
- IgniteClientSpringDataCompoundKeyTest.class
-})
-public class IgniteSpringData2TestSuite {
-}
diff --git a/modules/spring-data-2.2-ext/README.txt b/modules/spring-data-2.2-ext/README.txt
deleted file mode 100644
index f069dc0..0000000
--- a/modules/spring-data-2.2-ext/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Apache Ignite Spring Module
----------------------------
-
-Apache Ignite Spring Data 2.2 extension provides an integration with Spring Data 2.2 framework.
-
-Main features:
-
-- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
-- Supports query tuning parameters in @Query annotation
-- Supports projections
-- Supports Page and Stream responses
-- Supports Sql Fields Query resultset transformation into the domain entity
-- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
-- Supports advanced parameter binding and SpEL expressions into SQL queries:
-- Template variables:
- - #entityName - the simple class name of the domain entity
-- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
-- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
-- Supports SpEL expressions into Text queries (TextQuery).
-
-Importing Spring Data 2.2 extension In Maven Project
-----------------------------------------
-
-If you are using Maven to manage dependencies of your project, you can add Spring Data 2.2 extension
-dependency like this (replace '${ignite-spring-data-2.2-ext.version}' with actual version of Ignite Spring Data 2.2
-extension you are interested in):
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
- http://maven.apache.org/xsd/maven-4.0.0.xsd">
- ...
- <dependencies>
- ...
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.2-ext</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
- </dependency>
- ...
- </dependencies>
- ...
-</project>
diff --git a/modules/spring-data-2.2-ext/examples/config/example-default.xml b/modules/spring-data-2.2-ext/examples/config/example-default.xml
deleted file mode 100644
index e6c359d..0000000
--- a/modules/spring-data-2.2-ext/examples/config/example-default.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- Ignite configuration with all defaults and enabled p2p deployment and enabled events.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util.xsd">
- <bean abstract="true" id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
- <!-- Set to true to enable distributed class loading for examples, default is false. -->
- <property name="peerClassLoadingEnabled" value="true"/>
-
- <!-- Enable task execution events for examples. -->
- <property name="includeEventTypes">
- <list>
- <!--Task execution events-->
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/>
-
- <!--Cache events-->
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/>
- <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/>
- </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>
diff --git a/modules/spring-data-2.2-ext/examples/pom.xml b/modules/spring-data-2.2-ext/examples/pom.xml
deleted file mode 100644
index 04a69b1..0000000
--- a/modules/spring-data-2.2-ext/examples/pom.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-extensions-parent</artifactId>
- <version>1</version>
- <relativePath>../../../parent</relativePath>
- </parent>
-
- <artifactId>ignite-spring-data-2.2-ext-examples</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
- <url>http://ignite.apache.org</url>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.2-ext</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-indexing</artifactId>
- <version>${ignite.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.2.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring-5.2.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring-5.2.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring</artifactId>
- <version>${ignite.version}</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
-</project>
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
deleted file mode 100644
index 2127eaf..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/**
- * This class represents key for employee object.
- * <p>
- * Used in query example to collocate employees
- * with their organizations.
- */
-public class EmployeeKey {
- /** ID. */
- private int id;
-
- /** Organization ID. */
- @AffinityKeyMapped
- private int organizationId;
-
- /**
- * Required for binary deserialization.
- */
- public EmployeeKey() {
- // No-op.
- }
-
- /**
- * @param id ID.
- * @param organizationId Organization ID.
- */
- public EmployeeKey(int id, int organizationId) {
- this.id = id;
- this.organizationId = organizationId;
- }
-
- /**
- * @return ID.
- */
- public int id() {
- return id;
- }
-
- /**
- * @return Organization ID.
- */
- public int organizationId() {
- return organizationId;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- EmployeeKey key = (EmployeeKey)o;
-
- return id == key.id && organizationId == key.organizationId;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int res = id;
-
- res = 31 * res + organizationId;
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "EmployeeKey [id=" + id +
- ", organizationId=" + organizationId + ']';
- }
-}
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
deleted file mode 100644
index a6ba676..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import java.sql.Timestamp;
-import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-
-/**
- * This class represents organization object.
- */
-public class Organization {
- /** */
- private static final AtomicLong ID_GEN = new AtomicLong();
-
- /** Organization ID (indexed). */
- @QuerySqlField(index = true)
- private Long id;
-
- /** Organization name (indexed). */
- @QuerySqlField(index = true)
- private String name;
-
- /** Address. */
- private Address addr;
-
- /** Type. */
- private OrganizationType type;
-
- /** Last update time. */
- private Timestamp lastUpdated;
-
- /**
- * Required for binary deserialization.
- */
- public Organization() {
- // No-op.
- }
-
- /**
- * @param name Organization name.
- */
- public Organization(String name) {
- id = ID_GEN.incrementAndGet();
-
- this.name = name;
- }
-
- /**
- * @param id Organization ID.
- * @param name Organization name.
- */
- public Organization(long id, String name) {
- this.id = id;
- this.name = name;
- }
-
- /**
- * @param name Name.
- * @param addr Address.
- * @param type Type.
- * @param lastUpdated Last update time.
- */
- public Organization(String name, Address addr, OrganizationType type, Timestamp lastUpdated) {
- id = ID_GEN.incrementAndGet();
-
- this.name = name;
- this.addr = addr;
- this.type = type;
-
- this.lastUpdated = lastUpdated;
- }
-
- /**
- * @return Organization ID.
- */
- public Long id() {
- return id;
- }
-
- /**
- * @return Name.
- */
- public String name() {
- return name;
- }
-
- /**
- * @return Address.
- */
- public Address address() {
- return addr;
- }
-
- /**
- * @return Type.
- */
- public OrganizationType type() {
- return type;
- }
-
- /**
- * @return Last update time.
- */
- public Timestamp lastUpdated() {
- return lastUpdated;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Organization [id=" + id +
- ", name=" + name +
- ", address=" + addr +
- ", type=" + type +
- ", lastUpdated=" + lastUpdated + ']';
- }
-}
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java
deleted file mode 100644
index 585c458..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import java.io.Serializable;
-import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.cache.affinity.AffinityKey;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * Person class.
- */
-public class Person implements Serializable {
- /** */
- private static final AtomicLong ID_GEN = new AtomicLong();
-
- /** Person ID (indexed). */
- @QuerySqlField(index = true)
- public Long id;
-
- /** Organization ID (indexed). */
- @QuerySqlField(index = true)
- public Long orgId;
-
- /** First name (not-indexed). */
- @QuerySqlField
- public String firstName;
-
- /** Last name (not indexed). */
- @QuerySqlField
- public String lastName;
-
- /** Resume text (create LUCENE-based TEXT index for this field). */
- @QueryTextField
- public String resume;
-
- /** Salary (indexed). */
- @QuerySqlField(index = true)
- public double salary;
-
- /** Custom cache key to guarantee that person is always collocated with its organization. */
- private transient AffinityKey<Long> key;
-
- /**
- * Default constructor.
- */
- public Person() {
- // No-op.
- }
-
- /**
- * Constructs person record.
- *
- * @param org Organization.
- * @param firstName First name.
- * @param lastName Last name.
- * @param salary Salary.
- * @param resume Resume text.
- */
- public Person(Organization org, String firstName, String lastName, double salary, String resume) {
- // Generate unique ID for this person.
- id = ID_GEN.incrementAndGet();
-
- orgId = org.id();
-
- this.firstName = firstName;
- this.lastName = lastName;
- this.salary = salary;
- this.resume = resume;
- }
-
- /**
- * Constructs person record.
- *
- * @param id Person ID.
- * @param orgId Organization ID.
- * @param firstName First name.
- * @param lastName Last name.
- * @param salary Salary.
- * @param resume Resume text.
- */
- public Person(Long id, Long orgId, String firstName, String lastName, double salary, String resume) {
- this.id = id;
- this.orgId = orgId;
- this.firstName = firstName;
- this.lastName = lastName;
- this.salary = salary;
- this.resume = resume;
- }
-
- /**
- * Constructs person record.
- *
- * @param id Person ID.
- * @param firstName First name.
- * @param lastName Last name.
- */
- public Person(Long id, String firstName, String lastName) {
- this.id = id;
-
- this.firstName = firstName;
- this.lastName = lastName;
- }
-
- /**
- * Gets cache affinity key. Since in some examples person needs to be collocated with organization, we create
- * custom affinity key to guarantee this collocation.
- *
- * @return Custom affinity key to guarantee that person is always collocated with organization.
- */
- public AffinityKey<Long> key() {
- if (key == null)
- key = new AffinityKey<>(id, orgId);
-
- return key;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override public String toString() {
- return "Person [id=" + id +
- ", orgId=" + orgId +
- ", lastName=" + lastName +
- ", firstName=" + firstName +
- ", salary=" + salary +
- ", resume=" + resume + ']';
- }
-}
diff --git a/modules/spring-data-2.2-ext/licenses/apache-2.0.txt b/modules/spring-data-2.2-ext/licenses/apache-2.0.txt
deleted file mode 100644
index d645695..0000000
--- a/modules/spring-data-2.2-ext/licenses/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml b/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml
deleted file mode 100755
index 3061bd4..0000000
--- a/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
- "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-<!--
- Log4j configuration.
--->
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
- <!--
- Logs System.out messages to console.
- -->
- <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
- <!-- Log to STDOUT. -->
- <param name="Target" value="System.out"/>
-
- <!-- Log from DEBUG and higher. -->
- <param name="Threshold" value="DEBUG"/>
-
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
-
- <!-- Do not log beyond INFO level. -->
- <filter class="org.apache.log4j.varia.LevelRangeFilter">
- <param name="levelMin" value="DEBUG"/>
- <param name="levelMax" value="INFO"/>
- </filter>
- </appender>
-
- <!--
- Logs all System.err messages to console.
- -->
- <appender name="CONSOLE_ERR" class="org.apache.log4j.ConsoleAppender">
- <!-- Log to STDERR. -->
- <param name="Target" value="System.err"/>
-
- <!-- Log from WARN and higher. -->
- <param name="Threshold" value="WARN"/>
-
- <!-- The default pattern: Date Priority [Category] Message\n -->
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
- </appender>
-
- <!--
- Logs all output to specified file.
- -->
- <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
- <param name="Threshold" value="DEBUG"/>
- <param name="File" value="ignite/work/log/ignite.log"/>
- <param name="Append" value="true"/>
- <param name="MaxFileSize" value="10MB"/>
- <param name="MaxBackupIndex" value="10"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
- </layout>
- </appender>
-
- <!-- Disable all open source debugging. -->
- <category name="org">
- <level value="INFO"/>
- </category>
-
- <category name="org.eclipse.jetty">
- <level value="INFO"/>
- </category>
-
- <!-- Default settings. -->
- <root>
- <!-- Print at info by default. -->
- <level value="INFO"/>
-
- <!-- Append to file and console. -->
- <appender-ref ref="FILE"/>
- <appender-ref ref="CONSOLE"/>
- <appender-ref ref="CONSOLE_ERR"/>
- </root>
-</log4j:configuration>
diff --git a/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties b/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties
deleted file mode 100644
index 0faf5b8..0000000
--- a/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Local address to bind to.
-local.ip=127.0.0.1
-
-# TCP communication port
-comm.tcp.port=30010
diff --git a/modules/spring-data-2.2-ext/pom.xml b/modules/spring-data-2.2-ext/pom.xml
deleted file mode 100644
index 3db1ee1..0000000
--- a/modules/spring-data-2.2-ext/pom.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-extensions-parent</artifactId>
- <version>1</version>
- <relativePath>../../parent</relativePath>
- </parent>
-
- <artifactId>ignite-spring-data-2.2-ext</artifactId>
- <version>${ignite-spring-data-2.2-ext.version}</version>
- <url>http://ignite.apache.org</url>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-indexing</artifactId>
- <version>${ignite.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-commons</artifactId>
- <version>${ignite-spring-data-commons.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring-5.2.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring-5.2.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.2.version}</version>
- <scope>provided</scope>
- <!-- Exclude slf4j logging in favor of log4j -->
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>${commons.lang.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-log4j</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-tools</artifactId>
- <version>${ignite.version}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java
deleted file mode 100644
index 9a4e793..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository;
-
-import java.io.Serializable;
-import java.util.Map;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
- /**
- * Returns the Ignite instance bound to the repository
- *
- * @return the Ignite instance bound to the repository
- */
- public Ignite ignite();
-
- /**
- * Returns the Ignite Cache bound to the repository
- *
- * @return the Ignite Cache bound to the repository
- */
- public IgniteCache<K, V> cache();
-
- /**
- * Saves a given entity using provided key.
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Entity type.
- * @param key Entity's key.
- * @param entity Entity to save.
- * @return Saved entity.
- */
- public <S extends V> S save(K key, S entity);
-
- /**
- * Saves all given keys and entities combinations.
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Type of entities.
- * @param entities Map of key-entities pairs to save.
- * @return Saved entities.
- */
- public <S extends V> Iterable<S> save(Map<K, S> entities);
-
- /**
- * Saves a given entity using provided key with expiry policy
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Entity type.
- * @param key Entity's key.
- * @param entity Entity to save.
- * @param expiryPlc ExpiryPolicy to apply, if not null.
- * @return Saved entity.
- */
- public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
-
- /**
- * Saves all given keys and entities combinations with expiry policy
- * </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
- * (keys) that are not unique cluster wide.
- *
- * @param <S> Type of entities.
- * @param entities Map of key-entities pairs to save.
- * @param expiryPlc ExpiryPolicy to apply, if not null.
- * @return Saved entities.
- */
- public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
-
- /**
- * Deletes all the entities for the provided ids.
- *
- * @param ids List of ids to delete.
- */
- public void deleteAllById(Iterable<? extends K> ids);
-
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java
deleted file mode 100644
index 560ee2e..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryImpl;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Import;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-
-/**
- * Annotation to activate Apache Ignite repositories. If no base package is configured through either {@link #value()},
- * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-@Import(IgniteRepositoriesRegistar.class)
-public @interface EnableIgniteRepositories {
- /**
- * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
- * {@code @EnableIgniteRepositories("org.my.pkg")} instead of
- * {@code @EnableIgniteRepositories(basePackages="org.my.pkg")}.
- */
- String[] value() default {};
-
- /**
- * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with)
- * this attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
- */
- String[] basePackages() default {};
-
- /**
- * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components.
- * The package of each class specified will be scanned. Consider creating a special no-op marker class or interface
- * in each package that serves no purpose other than being referenced by this attribute.
- */
- Class<?>[] basePackageClasses() default {};
-
- /**
- * Specifies which types are not eligible for component scanning.
- */
- Filter[] excludeFilters() default {};
-
- /**
- * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
- * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or
- * filters.
- */
- Filter[] includeFilters() default {};
-
- /**
- * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
- * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
- * for {@code PersonRepositoryImpl}.
- *
- * @return Postfix to be used when looking up custom repository implementations.
- */
- String repositoryImplementationPostfix() default "Impl";
-
- /**
- * Configures the location of where to find the Spring Data named queries properties file.
- *
- * @return Location of where to find the Spring Data named queries properties file.
- */
- String namedQueriesLocation() default "";
-
- /**
- * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
- * {@link Key#CREATE_IF_NOT_FOUND}.
- *
- * @return Key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods.
- */
- Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
-
- /**
- * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
- * IgniteRepositoryFactoryBean}.
- *
- * @return {@link FactoryBean} class to be used for each repository instance.
- */
- Class<?> repositoryFactoryBeanClass() default IgniteRepositoryFactoryBean.class;
-
- /**
- * Configure the repository base class to be used to create repository proxies for this particular configuration.
- *
- * @return Repository base class to be used to create repository proxies for this particular configuration.
- */
- Class<?> repositoryBaseClass() default IgniteRepositoryImpl.class;
-
- /**
- * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
- * repositories infrastructure.
- */
- boolean considerNestedRepositories() default false;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java
deleted file mode 100644
index ddecd77..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Annotation;
-
-import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryBeanDefinitionRegistrarSupport}.
- */
-public class IgniteRepositoriesRegistar extends RepositoryBeanDefinitionRegistrarSupport {
- /** {@inheritDoc} */
- @Override protected Class<? extends Annotation> getAnnotation() {
- return EnableIgniteRepositories.class;
- }
-
- /** {@inheritDoc} */
- @Override protected RepositoryConfigurationExtension getExtension() {
- return new IgniteRepositoryConfigurationExtension();
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java
deleted file mode 100644
index cf6db05..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.util.Collection;
-import java.util.Collections;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.support.IgniteProxyFactory;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationSource;
-
-import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
- */
-public class IgniteRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
- /** Name of the auto-registered Ignite proxy factory bean. */
- private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
-
- /** Name of the auto-registered Ignite proxy bean prototype. */
- private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
-
- /** {@inheritDoc} */
- @Override public String getModuleName() {
- return "Apache Ignite";
- }
-
- /** {@inheritDoc} */
- @Override protected String getModulePrefix() {
- return "ignite";
- }
-
- /** {@inheritDoc} */
- @Override public String getRepositoryFactoryBeanClassName() {
- return IgniteRepositoryFactoryBean.class.getName();
- }
-
- /** {@inheritDoc} */
- @Override protected Collection<Class<?>> getIdentifyingTypes() {
- return Collections.singleton(IgniteRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
- registerIfNotAlreadyRegistered(
- () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
- registry,
- IGNITE_PROXY_FACTORY_BEAN_NAME,
- cfg);
-
- registerIfNotAlreadyRegistered(
- () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
- .setScope(SCOPE_PROTOTYPE)
- .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
- .getBeanDefinition(),
- registry,
- IGNITE_PROXY_BEAN_NAME,
- cfg);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java
deleted file mode 100644
index 1ea4bf3..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-
-/**
- * Annotation to provide a user defined query for a method.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Query {
- /**
- * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
- * (only if textQuery = false (default))
- */
- String value() default "";
-
- /**
- * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
- * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
- *
- * @see RepositoryConfig#igniteInstance()
- */
- boolean textQuery() default false;
-
- /**
- * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
- * statements or to not return hidden fields on SELECT * statements.
- */
- boolean forceFieldsQuery() default false;
-
- /**
- * Sets flag defining if this query is collocated.
- * <p>
- * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
- * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
- * of your query selection are collocated together on the same node and you group by collocated key (primary or
- * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
- * nodes.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean collocated() default false;
-
- /**
- * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
- * timeout is exceeded. Zero value disables timeout
- *
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- int timeout() default 0;
-
- /**
- * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
- * tables in join. By default is {@code false}.
- * <p>
- * It is not recommended to enable this property until you are sure that your indexes and the query itself are
- * correct and tuned as much as possible but query optimizer still produces wrong join order.
- *
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean enforceJoinOrder() default false;
-
- /**
- * Specify if distributed joins are enabled for this query.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- boolean distributedJoins() default false;
-
- /**
- * Sets lazy query execution flag.
- * <p>
- * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
- * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
- * increasing concurrency.
- * <p>
- * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
- * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
- * consumption at the cost of moderate performance hit.
- * <p>
- * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
- * <p>
- * Only applicable to SqlFieldsQuery
- */
- boolean lazy() default false;
-
- /**
- * Sets whether this query should be executed on local node only.
- */
- boolean local() default false;
-
- /**
- * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
- * partitions.
- * <p>
- * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
- * <p>
- * Only applicable to SqlFieldsQuery and SqlQuery
- */
- int[] parts() default {};
-
- /**
- * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
- * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
- * <p>
- * Please, note that {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
- * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
- */
- boolean dynamicQuery() default false;
-
- /**
- * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
- */
- int limit() default 0;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java
deleted file mode 100644
index e890052..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-
-/**
- * The annotation can be used to pass Ignite specific parameters to a bound repository.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-public @interface RepositoryConfig {
- /**
- * Cache name string.
- *
- * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
- */
- String cacheName() default "";
-
- /**
- * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
- * Ignite cluster.
- */
- String igniteInstance() default "igniteInstance";
-
- /**
- * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
- * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
- */
- String igniteCfg() default "igniteCfg";
-
- /**
- * Ignite spring cfg path string. Default "igniteSpringCfgPath".
- *
- * @return A path to Ignite's Spring XML configuration spring bean name
- */
- String igniteSpringCfgPath() default "igniteSpringCfgPath";
-
- /**
- * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
- * <p>
- * Tells to Ignite Repository factory wether cache should be auto created if not exists.
- *
- * @return the boolean
- */
- boolean autoCreateCache() default false;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java
deleted file mode 100644
index 4e3203b..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes Spring Data integration related configuration files.
- */
-package org.apache.ignite.springdata22.repository.config;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java
deleted file mode 100644
index 2a865f5..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains Apache Ignite Spring Data integration.
- */
-package org.apache.ignite.springdata22.repository;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java
deleted file mode 100644
index dad35e2..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.util.List;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.util.StringUtils;
-
-/**
- * A wrapper for a String representation of a query offering information about the query.
- *
- * @author Jens Schauder
- */
-interface DeclaredQuery {
- /**
- * Creates a {@literal DeclaredQuery} from a query {@literal String}.
- *
- * @param qry might be {@literal null} or empty.
- * @return a {@literal DeclaredQuery} instance even for a {@literal null} or empty argument.
- */
- public static DeclaredQuery of(@Nullable String qry) {
- return StringUtils.isEmpty(qry) ? EmptyDeclaredQuery.EMPTY_QUERY : new StringQuery(qry);
- }
-
- /**
- * @return whether the underlying query has at least one named parameter.
- */
- public boolean hasNamedParameter();
-
- /**
- * Returns the query string.
- */
- public String getQueryString();
-
- /**
- * Returns the main alias used in the query.
- *
- * @return the alias
- */
- @Nullable
- public String getAlias();
-
- /**
- * Returns whether the query is using a constructor expression.
- */
- public boolean hasConstructorExpression();
-
- /**
- * Returns whether the query uses the default projection, i.e. returns the main alias defined for the query.
- */
- public boolean isDefaultProjection();
-
- /**
- * Returns the {@link StringQuery.ParameterBinding}s registered.
- */
- public List<StringQuery.ParameterBinding> getParameterBindings();
-
- /**
- * Creates a new {@literal DeclaredQuery} representing a count query, i.e. a query returning the number of rows to
- * be expected from the original query, either derived from the query wrapped by this instance or from the
- * information passed as arguments.
- *
- * @param cntQry an optional query string to be used if present.
- * @param cntQryProjection an optional return type for the query.
- * @return a new {@literal DeclaredQuery} instance.
- */
- public DeclaredQuery deriveCountQuery(@Nullable String cntQry, @Nullable String cntQryProjection);
-
- /**
- * @return whether paging is implemented in the query itself, e.g. using SpEL expressions.
- */
- public default boolean usesPaging() {
- return false;
- }
-
- /**
- * Returns whether the query uses JDBC style parameters, i.e. parameters denoted by a simple ? without any index or
- * name.
- *
- * @return Whether the query uses JDBC style parameters.
- */
- public boolean usesJdbcStyleParameters();
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java
deleted file mode 100644
index b045a4f..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import org.apache.ignite.internal.util.typedef.internal.S;
-
-/**
- * Ignite query helper class. For internal use only.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteQuery {
- /** */
- enum Option {
- /** Query will be used with Sort object. */
- SORTING,
-
- /** Query will be used with Pageable object. */
- PAGINATION,
-
- /** No advanced option. */
- NONE
- }
-
- /**
- * Query text string.
- */
- private final String qrySql;
-
- /**
- * Whether this is a SQL fields query
- */
- private final boolean isFieldQuery;
-
- /**
- * Whether this is Text query
- */
- private final boolean isTextQuery;
-
- /**
- * Whether was autogenerated (by method name)
- */
- private final boolean isAutogenerated;
-
- /**
- * Type of option.
- */
- private final Option option;
-
- /**
- * @param qrySql the query string.
- * @param isFieldQuery Is field query.
- * @param isTextQuery Is a TextQuery
- * @param isAutogenerated query was autogenerated
- * @param option Option.
- */
- public IgniteQuery(String qrySql,
- boolean isFieldQuery,
- boolean isTextQuery,
- boolean isAutogenerated,
- Option option) {
- this.qrySql = qrySql;
- this.isFieldQuery = isFieldQuery;
- this.isTextQuery = isTextQuery;
- this.isAutogenerated = isAutogenerated;
- this.option = option;
- }
-
- /**
- * Text string of the query.
- *
- * @return SQL query text string.
- */
- public String qryStr() {
- return qrySql;
- }
-
- /**
- * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
- *
- * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
- */
- public boolean isFieldQuery() {
- return isFieldQuery;
- }
-
- /**
- * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
- *
- * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
- */
- public boolean isTextQuery() {
- return isTextQuery;
- }
-
- /**
- * Returns {@code true} if it's autogenerated, {@code false} otherwise.
- *
- * @return {@code true} if it's autogenerated, {@code false} otherwise.
- */
- public boolean isAutogenerated() {
- return isAutogenerated;
- }
-
- /**
- * Advanced querying option.
- *
- * @return querying option.
- */
- public Option options() {
- return option;
- }
-
- /** */
- @Override public String toString() {
- return S.toString(IgniteQuery.class, this);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java
deleted file mode 100644
index a0be11d..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.lang.reflect.Method;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.mapping.PropertyPath;
-import org.springframework.data.mapping.PropertyReferenceException;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.parser.Part;
-import org.springframework.data.repository.query.parser.PartTree;
-
-/**
- * Ignite query generator for Spring Data framework.
- */
-public class IgniteQueryGenerator {
- /** */
- private IgniteQueryGenerator() {
- // No-op.
- }
-
- /**
- * @param mtd Method.
- * @param metadata Metadata.
- * @return Generated ignite query.
- */
- public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
- PartTree parts;
-
- try {
- parts = new PartTree(mtd.getName(), metadata.getDomainType());
- }
- catch (PropertyReferenceException e) {
- parts = new PartTree(mtd.getName(), metadata.getIdType());
- }
-
- boolean isCountOrFieldQuery = parts.isCountProjection();
-
- StringBuilder sql = new StringBuilder();
-
- if (parts.isDelete()) {
- sql.append("DELETE ");
-
- // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
- isCountOrFieldQuery = true;
- }
- else {
- sql.append("SELECT ");
-
- if (parts.isDistinct())
- throw new UnsupportedOperationException("DISTINCT clause in not supported.");
-
- if (isCountOrFieldQuery)
- sql.append("COUNT(1) ");
- else
- sql.append("* ");
- }
-
- sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
-
- if (parts.iterator().hasNext()) {
- sql.append(" WHERE ");
-
- for (PartTree.OrPart orPart : parts) {
- sql.append("(");
-
- for (Part part : orPart) {
- handleQueryPart(sql, part, metadata.getDomainType());
- sql.append(" AND ");
- }
-
- sql.delete(sql.length() - 5, sql.length());
-
- sql.append(") OR ");
- }
-
- sql.delete(sql.length() - 4, sql.length());
- }
-
- addSorting(sql, parts.getSort());
-
- if (parts.isLimiting()) {
- sql.append(" LIMIT ");
- sql.append(parts.getMaxResults().intValue());
- }
-
- return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
- }
-
- /**
- * Add a dynamic part of query for the sorting support.
- *
- * @param sql SQL text string.
- * @param sort Sort method.
- * @return Sorting criteria in StringBuilder.
- */
- public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
- if (sort != null && sort != Sort.unsorted()) {
- sql.append(" ORDER BY ");
-
- for (Sort.Order order : sort) {
- sql.append(order.getProperty()).append(" ").append(order.getDirection());
-
- if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
- sql.append(" ").append("NULL ");
-
- switch (order.getNullHandling()) {
- case NULLS_FIRST:
- sql.append("FIRST");
- break;
- case NULLS_LAST:
- sql.append("LAST");
- break;
- default:
- }
- }
- sql.append(", ");
- }
-
- sql.delete(sql.length() - 2, sql.length());
- }
-
- return sql;
- }
-
- /**
- * Add a dynamic part of a query for the pagination support.
- *
- * @param sql Builder instance.
- * @param pageable Pageable instance.
- * @return Builder instance.
- */
- public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
-
- addSorting(sql, pageable.getSort());
-
- sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
-
- return sql;
- }
-
- /**
- * Determines whether query is dynamic or not (by list of method parameters)
- *
- * @param mtd Method.
- * @return type of options
- */
- public static IgniteQuery.Option getOptions(Method mtd) {
- IgniteQuery.Option option = IgniteQuery.Option.NONE;
-
- Class<?>[] types = mtd.getParameterTypes();
- if (types.length > 0) {
- Class<?> type = types[types.length - 1];
-
- if (Sort.class.isAssignableFrom(type))
- option = IgniteQuery.Option.SORTING;
- else if (Pageable.class.isAssignableFrom(type))
- option = IgniteQuery.Option.PAGINATION;
- }
-
- for (int i = 0; i < types.length - 1; i++) {
- Class<?> tp = types[i];
-
- if (tp == Sort.class || tp == Pageable.class)
- throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
- }
-
- return option;
- }
-
- /**
- * Check and correct table name if using column name from compound key.
- */
- private static String getColumnName(Part part, Class<?> domainType) {
- PropertyPath prperty = part.getProperty();
-
- if (prperty.getType() != domainType)
- return domainType.getSimpleName() + "." + prperty.getSegment();
- else
- return part.toString();
- }
-
- /**
- * Transform part to qryStr expression
- */
- private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
- sql.append("(");
-
- sql.append(getColumnName(part, domainType));
-
- switch (part.getType()) {
- case SIMPLE_PROPERTY:
- sql.append("=?");
- break;
- case NEGATING_SIMPLE_PROPERTY:
- sql.append("<>?");
- break;
- case GREATER_THAN:
- sql.append(">?");
- break;
- case GREATER_THAN_EQUAL:
- sql.append(">=?");
- break;
- case LESS_THAN:
- sql.append("<?");
- break;
- case LESS_THAN_EQUAL:
- sql.append("<=?");
- break;
- case IS_NOT_NULL:
- sql.append(" IS NOT NULL");
- break;
- case IS_NULL:
- sql.append(" IS NULL");
- break;
- case BETWEEN:
- sql.append(" BETWEEN ? AND ?");
- break;
- case FALSE:
- sql.append(" = FALSE");
- break;
- case TRUE:
- sql.append(" = TRUE");
- break;
- //TODO: review this legacy code, LIKE should be -> LIKE ?
- case LIKE:
- case CONTAINING:
- sql.append(" LIKE '%' || ? || '%'");
- break;
- case NOT_CONTAINING:
- //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
- case NOT_LIKE:
- sql.append(" NOT LIKE '%' || ? || '%'");
- break;
- case STARTING_WITH:
- sql.append(" LIKE ? || '%'");
- break;
- case ENDING_WITH:
- sql.append(" LIKE '%' || ?");
- break;
- case IN:
- sql.append(" IN ?");
- break;
- case NOT_IN:
- sql.append(" NOT IN ?");
- break;
- case REGEX:
- sql.append(" REGEXP ?");
- break;
- case NEAR:
- case AFTER:
- case BEFORE:
- case EXISTS:
- default:
- throw new UnsupportedOperationException(part.getType() + " is not supported!");
- }
-
- sql.append(")");
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
deleted file mode 100644
index 26b8fb9..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.cache.Cache;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.reflect.FieldUtils;
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.cache.query.FieldsQueryCursor;
-import org.apache.ignite.cache.query.Query;
-import org.apache.ignite.cache.query.QueryCursor;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.cache.query.SqlQuery;
-import org.apache.ignite.cache.query.TextQuery;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.springdata22.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata22.repository.query.StringQuery.ParameterBinding;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.SliceImpl;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.projection.ProjectionFactory;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.Parameter;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.StringUtils;
-
-import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
-import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
-import static org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactory.isFieldQuery;
-
-/**
- * Ignite query implementation.
- * <p>
- * <p>
- * Features:
- * <ol>
- * <li> Supports query tuning parameters</li>
- * <li> Supports projections</li>
- * <li> Supports Page and Stream responses</li>
- * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
- * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
- * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
- * <ol>
- * <li><b>Template variables</b>:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the domain entity</li>
- * </ol>
- * </li>
- * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
- * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
- * ?#{[0]} or ?#{#myParamName}</li>
- * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
- * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
- * through SpEL EvaluationContext extension model.</li>
- * </ol>
- * Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
- * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
- * Pageable pageable);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
- * User searchUserByEmail(String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
- * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
- * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
- * <pre>
- * {@code @Query}(textQuery = true, value = "email: #{#email}")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
- * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{[0]}")
- * List<User> searchUsersByText(String textToSearch, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
- * .match('city', #city)).build()}")
- * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
- *
- * {@code @Query}(dynamicQuery = true)
- * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
- * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
- *
- * ...
- * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
- * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
- *
- * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
- * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
- *
- * </pre>
- * </li>
- * </ol>
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@SuppressWarnings("unchecked")
-public class IgniteRepositoryQuery implements RepositoryQuery {
- /**
- * Defines the way how to process query result
- */
- private enum ReturnStrategy {
- /** Need to return only one value. */
- ONE_VALUE,
-
- /** Need to return one cache entry */
- CACHE_ENTRY,
-
- /** Need to return list of cache entries */
- LIST_OF_CACHE_ENTRIES,
-
- /** Need to return list of values */
- LIST_OF_VALUES,
-
- /** Need to return list of lists */
- LIST_OF_LISTS,
-
- /** Need to return slice */
- SLICE_OF_VALUES,
-
- /** Slice of cache entries */
- SLICE_OF_CACHE_ENTRIES,
-
- /** Slice of lists */
- SLICE_OF_LISTS,
-
- /** Need to return Page of values */
- PAGE_OF_VALUES,
-
- /** Need to return stream of values */
- STREAM_OF_VALUES,
- }
-
- /** */
- private final Class<?> type;
-
- /** Domain entitiy field descriptors mapped to their names in lower case. */
- private final Map<String, Field> domainEntitiyFields;
-
- /** */
- private final IgniteQuery staticQuery;
-
- /** */
- private final IgniteCacheProxy<?, ?> cache;
-
- /** */
- private final Method mtd;
-
- /** */
- private final RepositoryMetadata metadata;
-
- /** */
- private final ProjectionFactory factory;
-
- /** */
- private final ReturnStrategy staticReturnStgy;
-
- /** Detect if returned data from method is projected */
- private final boolean hasProjection;
-
- /** Whether projection is dynamic (provided as method parameter) */
- private final boolean hasDynamicProjection;
-
- /** Dynamic projection parameter index */
- private final int dynamicProjectionIndex;
-
- /** Dynamic query configuration */
- private final int dynamicQueryConfigurationIndex;
-
- /** The return query method */
- private final QueryMethod qMethod;
-
- /** The return domain class of QueryMethod */
- private final Class<?> returnedDomainClass;
-
- /** */
- private final SpelExpressionParser expressionParser;
-
- /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
- private final QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider;
-
- /** Static query configuration. */
- private final DynamicQueryConfig staticQueryConfiguration;
-
- /**
- * Instantiates a new Ignite repository query.
- *
- * @param metadata Metadata.
- * @param staticQuery Query.
- * @param mtd Method.
- * @param factory Factory.
- * @param cache Cache.
- * @param staticQueryConfiguration the query configuration
- * @param queryMethodEvaluationContextProvider the query method evaluation context provider
- */
- public IgniteRepositoryQuery(
- RepositoryMetadata metadata,
- @Nullable IgniteQuery staticQuery,
- Method mtd,
- ProjectionFactory factory,
- IgniteCacheProxy<? ,?> cache,
- @Nullable DynamicQueryConfig staticQueryConfiguration,
- QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider) {
- this.metadata = metadata;
- this.mtd = mtd;
- this.factory = factory;
- type = metadata.getDomainType();
-
- domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
- .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
-
- this.cache = cache;
-
- this.staticQueryConfiguration = staticQueryConfiguration;
- this.staticQuery = staticQuery;
-
- if (this.staticQuery != null)
- staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
- else
- staticReturnStgy = null;
-
- expressionParser = new SpelExpressionParser();
- this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
-
- qMethod = getQueryMethod();
-
- // control projection
- hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
- hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
- .isProjecting();
-
- dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
-
- returnedDomainClass = getQueryMethod().getReturnedObjectType();
-
- dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
-
- // ensure dynamic query configuration param exists if dynamicQuery = true
- if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
- throw new IllegalStateException(
- "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
- + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
- }
- }
-
- /**
- * {@inheritDoc} @param values the values
- *
- * @return the object
- */
- @Override public Object execute(Object[] values) {
- Object[] parameters = values;
-
- // config via Query annotation (dynamicQuery = false)
- DynamicQueryConfig config = staticQueryConfiguration;
-
- // or condition to allow query tunning
- if (config == null || dynamicQueryConfigurationIndex != -1) {
- DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
- parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
- if (newConfig != null) {
- // upset query configuration
- config = newConfig;
- }
- }
- // query configuration is required, via Query annotation or per parameter (within provided values param)
- if (config == null) {
- throw new IllegalStateException(
- "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
- + ".repository.config.Query annotation, you must provide a non null method parameter of type "
- + "DynamicQueryConfig");
- }
-
- IgniteQuery qry = getQuery(config);
-
- ReturnStrategy returnStgy = getReturnStgy(qry);
-
- Query iQry = prepareQuery(qry, config, returnStgy, parameters);
-
- QueryCursor qryCursor;
-
- try {
- qryCursor = cache.query(iQry);
- }
- catch (IllegalArgumentException e) {
- if (cache instanceof IgniteClientCacheProxy) {
- throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
- " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
- iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
- }
-
- throw e;
- }
-
- return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
- }
-
- /** {@inheritDoc} */
- @Override public QueryMethod getQueryMethod() {
- return new QueryMethod(mtd, metadata, factory);
- }
-
- private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
- Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
- int i = 0;
- boolean found = false;
- int index = -1;
- while (it.hasNext()) {
- T parameter = it.next();
-
- if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
- if (found) {
- throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
- + "Only ONE DynamicQueryConfig parameter is allowed");
- }
-
- found = true;
- index = i;
- }
-
- i++;
- }
- return index;
- }
-
- /**
- * @param mtd Method.
- * @param isFieldQry Is field query.
- * @return Return strategy type.
- */
- private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
- Class<?> returnType = mtd.getReturnType();
-
- if (returnType == Slice.class) {
- if (isFieldQry) {
- if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
- return ReturnStrategy.SLICE_OF_LISTS;
- }
- else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
- return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
- return ReturnStrategy.SLICE_OF_VALUES;
- }
- else if (returnType == Page.class)
- return ReturnStrategy.PAGE_OF_VALUES;
- else if (returnType == Stream.class)
- return ReturnStrategy.STREAM_OF_VALUES;
- else if (Cache.Entry.class.isAssignableFrom(returnType))
- return ReturnStrategy.CACHE_ENTRY;
- else if (Iterable.class.isAssignableFrom(returnType)) {
- if (isFieldQry) {
- if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
- return ReturnStrategy.LIST_OF_LISTS;
- }
- else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
- return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
- return ReturnStrategy.LIST_OF_VALUES;
- }
- else
- return ReturnStrategy.ONE_VALUE;
- }
-
- /**
- * @param cls Class.
- * @param mtd Method.
- * @return if {@code mtd} return type is assignable from {@code cls}
- */
- private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
- Type genericReturnType = mtd.getGenericReturnType();
-
- if (!(genericReturnType instanceof ParameterizedType))
- return false;
-
- Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
-
- if (actualTypeArguments.length == 0)
- return false;
-
- if (actualTypeArguments[0] instanceof ParameterizedType) {
- ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
-
- Class<?> type1 = (Class)type.getRawType();
-
- return type1.isAssignableFrom(cls);
- }
-
- if (actualTypeArguments[0] instanceof Class) {
- Class typeArg = (Class)actualTypeArguments[0];
-
- return typeArg.isAssignableFrom(cls);
- }
-
- return false;
- }
-
- /**
- * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
- *
- * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
- * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
- */
- private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
- if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
- return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
-
- return (T)object;
- }
-
- /**
- * @param cfg Config.
- */
- private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
- if (staticQuery != null)
- return staticQuery;
-
- if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
- return new IgniteQuery(cfg.value(),
- !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
- false, IgniteQueryGenerator.getOptions(mtd));
- }
-
- throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
- + ".apache.ignite.springdata.repository.config.Query annotation, you must"
- + " provide a non null method parameter of type DynamicQueryConfig with a "
- + "non empty value (query string) or textQuery = true");
- }
-
- /**
- * @param qry Query.
- */
- private ReturnStrategy getReturnStgy(IgniteQuery qry) {
- if (staticReturnStgy != null)
- return staticReturnStgy;
-
- if (qry != null)
- return calcReturnType(mtd, qry.isFieldQuery());
-
- throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
- + "via org.apache.ignite.springdata.repository.config.Query annotation, "
- + "you must provide a non null method parameter of type "
- + "DynamicQueryConfig with a non empty value (query string) or textQuery "
- + "= true");
- }
-
- /**
- * @param cls Class.
- */
- private static boolean isPrimitiveOrWrapper(Class<?> cls) {
- return cls.isPrimitive() ||
- Boolean.class.equals(cls) ||
- Byte.class.equals(cls) ||
- Character.class.equals(cls) ||
- Short.class.equals(cls) ||
- Integer.class.equals(cls) ||
- Long.class.equals(cls) ||
- Float.class.equals(cls) ||
- Double.class.equals(cls) ||
- Void.class.equals(cls) ||
- String.class.equals(cls) ||
- UUID.class.equals(cls);
- }
-
- /**
- * @param prmtrs Prmtrs.
- * @param qryCursor Query cursor.
- * @return Query cursor or slice
- */
- @Nullable
- private Object transformQueryCursor(IgniteQuery qry,
- ReturnStrategy returnStgy,
- Object[] prmtrs,
- QueryCursor qryCursor) {
- final Class<?> returnClass;
-
- if (hasProjection) {
- if (hasDynamicProjection)
- returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
- else
- returnClass = returnedDomainClass;
- }
- else
- returnClass = returnedDomainClass;
-
- if (qry.isFieldQuery()) {
- // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
- boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
-
- FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
-
- Function<List<?>, ?> cWrapperTransformFunction = null;
-
- if (type.equals(returnClass))
- cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
- else {
- if (hasProjection || singlePrimitiveResult) {
- if (singlePrimitiveResult)
- cWrapperTransformFunction = row -> row.get(0);
- else {
- // Map row -> projection class
- cWrapperTransformFunction = row -> factory
- .createProjection(returnClass, rowToMap(row, fieldQryCur));
- }
- }
- else
- cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
- }
-
- QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
- cWrapperTransformFunction);
-
- switch (returnStgy) {
- case PAGE_OF_VALUES:
- return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
- case LIST_OF_VALUES:
- return cWrapper.getAll();
- case STREAM_OF_VALUES:
- return cWrapper.stream();
- case ONE_VALUE:
- Iterator<?> iter = cWrapper.iterator();
- if (iter.hasNext()) {
- Object resp = iter.next();
- U.closeQuiet(cWrapper);
- return resp;
- }
- return null;
- case SLICE_OF_VALUES:
- return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case SLICE_OF_LISTS:
- return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case LIST_OF_LISTS:
- return qryCursor.getAll();
- default:
- throw new IllegalStateException();
- }
- }
- else {
- Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
-
- if (hasProjection && !type.equals(returnClass))
- cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
- else
- cWrapperTransformFunction = Cache.Entry::getValue;
-
- QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
- (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
-
- switch (returnStgy) {
- case PAGE_OF_VALUES:
- return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
- case LIST_OF_VALUES:
- return cWrapper.getAll();
- case STREAM_OF_VALUES:
- return cWrapper.stream();
- case ONE_VALUE:
- Iterator<?> iter1 = cWrapper.iterator();
- if (iter1.hasNext()) {
- Object resp = iter1.next();
- U.closeQuiet(cWrapper);
- return resp;
- }
- return null;
- case CACHE_ENTRY:
- Iterator<?> iter2 = qryCursor.iterator();
- if (iter2.hasNext()) {
- Object resp2 = iter2.next();
- U.closeQuiet(qryCursor);
- return resp2;
- }
- return null;
- case SLICE_OF_VALUES:
- return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case SLICE_OF_CACHE_ENTRIES:
- return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
- case LIST_OF_CACHE_ENTRIES:
- return qryCursor.getAll();
- default:
- throw new IllegalStateException();
- }
- }
- }
-
- /**
- * Extract bindable values
- *
- * @param values values invoking query method
- * @param queryMethodParams query method parameter definitions
- * @param queryBindings All parameters found on query string that need to be binded
- * @return new list of parameters
- */
- private Object[] extractBindableValues(Object[] values,
- Parameters<?, ?> queryMethodParams,
- List<ParameterBinding> queryBindings) {
- // no binding params then exit
- if (queryBindings.isEmpty())
- return values;
-
- Object[] newValues = new Object[queryBindings.size()];
-
- // map bindable parameters from query method: (index/name) - index
- HashMap<String, Integer> methodParams = new HashMap<>();
-
- // create an evaluation context for custom query
- EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
- .getEvaluationContext(queryMethodParams, values);
-
- // By default queryEvalContext:
- // - make accesible query method parameters by index:
- // @Query("select u from User u where u.age = ?#{[0]}")
- // List<User> findUsersByAge(int age);
- // - make accesible query method parameters by name:
- // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
- // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
-
- // query method param's index by name and position
- queryMethodParams.getBindableParameters().forEach(p -> {
- if (p.isNamedParameter()) {
- // map by name (annotated by @Param)
- methodParams.put(p.getName().get(), p.getIndex());
- }
- // map by position
- methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
- });
-
- // process all parameters on query and extract new values to bind
- for (int i = 0; i < queryBindings.size(); i++) {
- ParameterBinding p = queryBindings.get(i);
-
- if (p.isExpression()) {
- // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
- newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
- }
- else {
- // Extract parameter value by name or position respectively from invoking values
- newValues[i] = values[methodParams.get(
- p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
- }
- }
-
- return newValues;
- }
-
- /**
- * @param qry Query.
- * @param config Config.
- * @param returnStgy Return stgy.
- * @param values Values.
- * @return prepared query for execution
- */
- private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
- Object[] parameters = values;
-
- String queryString = qry.qryStr();
-
- Query query;
-
- checkRequiredPageable(returnStgy, values);
-
- if (!qry.isTextQuery()) {
- if (!qry.isAutogenerated()) {
- StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
- queryString = squery.getQueryString();
- parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
- squery.getParameterBindings());
- }
- else {
- // remove dynamic projection from parameters
- if (hasDynamicProjection)
- parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
- }
-
- switch (qry.options()) {
- case SORTING:
- queryString = IgniteQueryGenerator
- .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
- .toString();
- if (qry.isAutogenerated())
- parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
- break;
- case PAGINATION:
- queryString = IgniteQueryGenerator
- .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
- .toString();
- if (qry.isAutogenerated())
- parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
- break;
- default:
- }
-
- if (qry.isFieldQuery()) {
- SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
- sqlFieldsQry.setArgs(parameters);
-
- sqlFieldsQry.setCollocated(config.collocated());
- sqlFieldsQry.setDistributedJoins(config.distributedJoins());
- sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
- sqlFieldsQry.setLazy(config.lazy());
- sqlFieldsQry.setLocal(config.local());
-
- if (config.parts() != null && config.parts().length > 0)
- sqlFieldsQry.setPartitions(config.parts());
-
- sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
- query = sqlFieldsQry;
- }
- else {
- SqlQuery sqlQry = new SqlQuery(type, queryString);
- sqlQry.setArgs(parameters);
-
- sqlQry.setDistributedJoins(config.distributedJoins());
- sqlQry.setLocal(config.local());
-
- if (config.parts() != null && config.parts().length > 0)
- sqlQry.setPartitions(config.parts());
-
- sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
- query = sqlQry;
- }
- }
- else {
- int pageSize = -1;
-
- switch (qry.options()) {
- case PAGINATION:
- pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
- break;
- }
-
- // check if queryString contains SpEL template expressions and evaluate them if any
- if (queryString.contains("#{")) {
- EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
- .getEvaluationContext(getQueryMethod().getParameters(),
- values);
-
- Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
- .getValue(queryEvalContext);
-
- if (!(eval instanceof String)) {
- throw new IllegalStateException(
- "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
- .getName()
- + ". Please, check your expression: " + queryString);
- }
- queryString = (String)eval;
- }
-
- TextQuery textQuery = new TextQuery(type, queryString, config.limit());
-
- textQuery.setLocal(config.local());
-
- if (pageSize > -1)
- textQuery.setPageSize(pageSize);
-
- query = textQuery;
- }
- return query;
- }
-
- /**
- * @param row SQL result row.
- * @param cursor SQL query result cursor through which {@param row} was obtained.
- * @return SQL result row values mapped to corresponding column names.
- */
- private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
- // use treemap with case insensitive property name
- final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
- for (int i = 0; i < row.size(); i++) {
- // don't want key or val columns
- final String fieldName = cursor.getFieldName(i).toLowerCase();
-
- if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
- map.put(fieldName, row.get(i));
- }
-
- return map;
- }
-
- /**
- * convert row ( with list of field values) into domain entity
- *
- * @param row SQL query result row.
- * @param cursor SQL query result cursor through which {@param row} was obtained.
- * @return Entitiy instance.
- */
- private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
- Constructor<?> ctor;
-
- try {
- ctor = type.getDeclaredConstructor();
-
- ctor.setAccessible(true);
- }
- catch (NoSuchMethodException | SecurityException ignored) {
- ctor = null;
- }
-
- try {
- Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
-
- for (int i = 0; i < row.size(); i++) {
- Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
-
- if (entityField != null)
- FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
- }
-
- return (V)res;
- }
- catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
- throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
- }
- }
-
- /**
- * Validates operations that requires Pageable parameter
- *
- * @param returnStgy Return stgy.
- * @param prmtrs Prmtrs.
- */
- private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
- try {
- if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
- || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
- Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
- page.isPaged();
- }
- }
- catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
- throw new IllegalStateException(
- "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
- }
- }
-
- /**
- * Ignite QueryCursor wrapper.
- * <p>
- * Ensures closing underline cursor when there is no data.
- *
- * @param <T> input type
- * @param <V> transformed output type
- */
- public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
- /**
- * Delegate query cursor.
- */
- private final QueryCursor<T> delegate;
-
- /**
- * Transformer.
- */
- private final Function<T, V> transformer;
-
- /**
- * Instantiates a new Query cursor wrapper.
- *
- * @param delegate delegate QueryCursor with T input elements
- * @param transformer Function to transform T to V elements
- */
- public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
- this.delegate = delegate;
- this.transformer = transformer;
- }
-
- /** {@inheritDoc} */
- @Override public Iterator<V> iterator() {
- final Iterator<T> it = delegate.iterator();
-
- return new Iterator<V>() {
- /** */
- @Override public boolean hasNext() {
- if (!it.hasNext()) {
- U.closeQuiet(delegate);
- return false;
- }
- return true;
- }
-
- /** */
- @Override public V next() {
- final V r = transformer.apply(it.next());
- if (r != null)
- return r;
- throw new NoSuchElementException();
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override public void close() {
- U.closeQuiet(delegate);
- }
-
- /** {@inheritDoc} */
- @Override public List<V> getAll() {
- final List<V> data = new ArrayList<>();
- delegate.forEach(i -> data.add(transformer.apply(i)));
- U.closeQuiet(delegate);
- return data;
- }
-
- /** {@inheritDoc} */
- @Override public int size() {
- return 0;
- }
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java
deleted file mode 100644
index 90cc292..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.util.Streamable;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-import static java.util.regex.Pattern.DOTALL;
-import static java.util.regex.Pattern.compile;
-
-/**
- * Simple utility class to create queries.
- *
- * @author Oliver Gierke
- * @author Kevin Raymond
- * @author Thomas Darimont
- * @author Komi Innocent
- * @author Christoph Strobl
- * @author Mark Paluch
- * @author Sébastien Péralta
- * @author Jens Schauder
- * @author Nils Borrmann
- * @author Reda.Housni -Alaoui
- */
-public abstract class QueryUtils {
- /**
- * The constant COUNT_QUERY_STRING.
- */
- public static final String COUNT_QUERY_STRING = "select count(%s) from %s x";
-
- /**
- * The constant DELETE_ALL_QUERY_STRING.
- */
- public static final String DELETE_ALL_QUERY_STRING = "delete from %s x";
-
- /**
- * Used Regex/Unicode categories (see http://www.unicode.org/reports/tr18/#General_Category_Property): Z Separator
- * Cc Control Cf Format P Punctuation
- */
- private static final String IDENTIFIER = "[._[\\P{Z}&&\\P{Cc}&&\\P{Cf}&&\\P{P}]]+";
-
- /**
- * The Colon no double colon.
- */
- static final String COLON_NO_DOUBLE_COLON = "(?<![:\\\\]):";
-
- /**
- * The Identifier group.
- */
- static final String IDENTIFIER_GROUP = String.format("(%s)", IDENTIFIER);
-
- /** */
- private static final String COUNT_REPLACEMENT_TEMPLATE = "select count(%s) $5$6$7";
-
- /** */
- private static final String SIMPLE_COUNT_VALUE = "$2";
-
- /** */
- private static final String COMPLEX_COUNT_VALUE = "$3$6";
-
- /** */
- private static final String ORDER_BY_PART = "(?iu)\\s+order\\s+by\\s+.*$";
-
- /** */
- private static final Pattern ALIAS_MATCH;
-
- /** */
- private static final Pattern COUNT_MATCH;
-
- /** */
- private static final Pattern PROJECTION_CLAUSE = Pattern
- .compile("select\\s+(.+)\\s+from", Pattern.CASE_INSENSITIVE);
-
- /** */
- private static final String JOIN = "join\\s+(fetch\\s+)?" + IDENTIFIER + "\\s+(as\\s+)?" + IDENTIFIER_GROUP;
-
- /** */
- private static final Pattern JOIN_PATTERN = Pattern.compile(JOIN, Pattern.CASE_INSENSITIVE);
-
- /** */
- private static final String EQUALS_CONDITION_STRING = "%s.%s = :%s";
-
- /** */
- private static final Pattern NAMED_PARAMETER = Pattern.compile(
- COLON_NO_DOUBLE_COLON + IDENTIFIER + "|\\#" + IDENTIFIER, CASE_INSENSITIVE);
-
- /** */
- private static final Pattern CONSTRUCTOR_EXPRESSION;
-
- /** */
- private static final int QUERY_JOIN_ALIAS_GROUP_INDEX = 3;
-
- /** */
- private static final int VARIABLE_NAME_GROUP_INDEX = 4;
-
- /** */
- private static final Pattern FUNCTION_PATTERN;
-
- static {
- StringBuilder builder = new StringBuilder();
- builder.append("(?<=from)"); // from as starting delimiter
- builder.append("(?:\\s)+"); // at least one space separating
- builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any
- builder.append("(?:\\sas)*"); // exclude possible "as" keyword
- builder.append("(?:\\s)+"); // at least one space separating
- builder.append("(?!(?:where))(\\w+)"); // the actual alias
-
- ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE);
-
- builder = new StringBuilder();
- builder.append("(select\\s+((distinct )?(.+?)?)\\s+)?(from\\s+");
- builder.append(IDENTIFIER);
- builder.append("(?:\\s+as)?\\s+)");
- builder.append(IDENTIFIER_GROUP);
- builder.append("(.*)");
-
- COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE);
-
- builder = new StringBuilder();
- builder.append("select");
- builder.append("\\s+"); // at least one space separating
- builder.append("(.*\\s+)?"); // anything in between (e.g. distinct) at least one space separating
- builder.append("new");
- builder.append("\\s+"); // at least one space separating
- builder.append(IDENTIFIER);
- builder.append("\\s*"); // zero to unlimited space separating
- builder.append("\\(");
- builder.append(".*");
- builder.append("\\)");
-
- CONSTRUCTOR_EXPRESSION = compile(builder.toString(), CASE_INSENSITIVE + DOTALL);
-
- builder = new StringBuilder();
- // any function call including parameters within the brackets
- builder.append("\\w+\\s*\\([\\w\\.,\\s'=]+\\)");
- // the potential alias
- builder.append("\\s+[as|AS]+\\s+(([\\w\\.]+))");
-
- FUNCTION_PATTERN = compile(builder.toString());
- }
-
- /**
- * Private constructor to prevent instantiation.
- */
- private QueryUtils() {
- // No-op.
- }
-
- /**
- * Returns the query string to execute an exists query for the given id attributes.
- *
- * @param entityName the name of the entity to create the query for, must not be {@literal null}.
- * @param cntQryPlaceHolder the placeholder for the count clause, must not be {@literal null}.
- * @param idAttrs the id attributes for the entity, must not be {@literal null}.
- * @return the exists query string
- */
- public static String getExistsQueryString(String entityName,
- String cntQryPlaceHolder,
- Iterable<String> idAttrs) {
- String whereClause = Streamable.of(idAttrs).stream() //
- .map(idAttribute -> String.format(EQUALS_CONDITION_STRING, "x", idAttribute,
- idAttribute)) //
- .collect(Collectors.joining(" AND ", " WHERE ", ""));
-
- return String.format(COUNT_QUERY_STRING, cntQryPlaceHolder, entityName) + whereClause;
- }
-
- /**
- * Returns the query string for the given class name.
- *
- * @param template must not be {@literal null}.
- * @param entityName must not be {@literal null}.
- * @return the template with placeholders replaced by the {@literal entityName}. Guaranteed to be not {@literal
- * null}.
- */
- public static String getQueryString(String template, String entityName) {
- Assert.hasText(entityName, "Entity name must not be null or empty!");
-
- return String.format(template, entityName);
- }
-
- /**
- * Returns the aliases used for {@code left (outer) join}s.
- *
- * @param qry a query string to extract the aliases of joins from. Must not be {@literal null}.
- * @return a {@literal Set} of aliases used in the query. Guaranteed to be not {@literal null}.
- */
- static Set<String> getOuterJoinAliases(String qry) {
- Set<String> result = new HashSet<>();
- Matcher matcher = JOIN_PATTERN.matcher(qry);
-
- while (matcher.find()) {
- String alias = matcher.group(QUERY_JOIN_ALIAS_GROUP_INDEX);
- if (StringUtils.hasText(alias))
- result.add(alias);
- }
-
- return result;
- }
-
- /**
- * Returns the aliases used for aggregate functions like {@code SUM, COUNT, ...}.
- *
- * @param qry a {@literal String} containing a query. Must not be {@literal null}.
- * @return a {@literal Set} containing all found aliases. Guaranteed to be not {@literal null}.
- */
- static Set<String> getFunctionAliases(String qry) {
- Set<String> result = new HashSet<>();
- Matcher matcher = FUNCTION_PATTERN.matcher(qry);
-
- while (matcher.find()) {
- String alias = matcher.group(1);
-
- if (StringUtils.hasText(alias))
- result.add(alias);
- }
-
- return result;
- }
-
- /**
- * Resolves the alias for the entity to be retrieved from the given JPA query.
- *
- * @param qry must not be {@literal null}.
- * @return Might return {@literal null}.
- */
- @Nullable
- static String detectAlias(String qry) {
- Matcher matcher = ALIAS_MATCH.matcher(qry);
-
- return matcher.find() ? matcher.group(2) : null;
- }
-
- /**
- * Creates a count projected query from the given original query.
- *
- * @param originalQry must not be {@literal null}.
- * @param cntProjection may be {@literal null}.
- * @return a query String to be used a count query for pagination. Guaranteed to be not {@literal null}.
- */
- static String createCountQueryFor(String originalQry, @Nullable String cntProjection) {
- Assert.hasText(originalQry, "OriginalQuery must not be null or empty!");
-
- Matcher matcher = COUNT_MATCH.matcher(originalQry);
- String countQuery;
-
- if (cntProjection == null) {
- String variable = matcher.matches() ? matcher.group(VARIABLE_NAME_GROUP_INDEX) : null;
- boolean useVariable = variable != null && StringUtils.hasText(variable) && !variable.startsWith("new")
- && !variable.startsWith("count(") && !variable.contains(",");
-
- String replacement = useVariable ? SIMPLE_COUNT_VALUE : COMPLEX_COUNT_VALUE;
- countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, replacement));
- }
- else
- countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, cntProjection));
-
- return countQuery.replaceFirst(ORDER_BY_PART, "");
- }
-
- /**
- * Returns whether the given JPQL query contains a constructor expression.
- *
- * @param qry must not be {@literal null} or empty.
- * @return boolean
- */
- public static boolean hasConstructorExpression(String qry) {
- Assert.hasText(qry, "Query must not be null or empty!");
-
- return CONSTRUCTOR_EXPRESSION.matcher(qry).find();
- }
-
- /**
- * Returns the projection part of the query, i.e. everything between {@code select} and {@code from}.
- *
- * @param qry must not be {@literal null} or empty.
- * @return projection
- */
- public static String getProjection(String qry) {
- Assert.hasText(qry, "Query must not be null or empty!");
-
- Matcher matcher = PROJECTION_CLAUSE.matcher(qry);
- String projection = matcher.find() ? matcher.group(1) : "";
- return projection.trim();
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java
deleted file mode 100644
index cfa3801..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes classes that integrates with Apache Ignite SQL engine.
- */
-package org.apache.ignite.springdata22.repository.query;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java
deleted file mode 100644
index 33d3757..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.support;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.config.BeanExpressionResolver;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-
-import static org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactory.getRepositoryConfiguration;
-
-/**
- * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
- * Ignite cluster.
- */
-public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
- /** Spring application expression resolver. */
- private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
-
- /** Repositories associated with Ignite proxy. */
- private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
-
- /** Spring application context. */
- private ApplicationContext ctx;
-
- /** Spring application bean expression context. */
- private BeanExpressionContext beanExpressionCtx;
-
- /**
- * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
- * @return {@link IgniteProxy} instance.
- */
- public IgniteProxy igniteProxy(Class<?> repoInterface) {
- return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
- }
-
- /** {@inheritDoc} */
- @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
- this.ctx = ctx;
-
- beanExpressionCtx = new BeanExpressionContext(
- new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
- null);
- }
-
- /** {@inheritDoc} */
- @Override public void destroy() throws Exception {
- Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
-
- Exception destroyE = null;
-
- for (IgniteProxy proxy : proxies) {
- if (proxy instanceof AutoCloseable) {
- try {
- ((AutoCloseable)proxy).close();
- }
- catch (Exception e) {
- if (destroyE == null)
- destroyE = e;
- else
- destroyE.addSuppressed(e);
- }
- }
- }
-
- if (destroyE != null)
- throw destroyE;
- }
-
- /**
- * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
- *
- * @param repoInterface {@link Class} instance of the repository interface.
- * @return Instance of {@link IgniteProxy} associated with specified repository.
- *
- * @see RepositoryConfig
- */
- private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
- RepositoryConfig repoCfg = getRepositoryConfiguration(repoInterface);
-
- return Stream.<BeanFinder>of(
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
- () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
- () -> ctx.getBean(Ignite.class),
- () -> ctx.getBean(IgniteClient.class),
- () -> ctx.getBean(IgniteConfiguration.class),
- () -> ctx.getBean(ClientConfiguration.class)
- ).map(BeanFinder::getBean)
- .filter(Objects::nonNull)
- .findFirst()
- .map(IgniteProxy::of)
- .orElseThrow(() -> {
- return new IllegalArgumentException("Invalid configuration for repository " +
- repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
- " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
- " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
- " ClientConfiguration or IgniteConfiguration bean to application context.");
- });
- }
-
- /**
- * Evaluates the SpEL expression.
- *
- * @param spelExpression SpEL expression
- * @return The result of evaluation of the SpEL expression.
- */
- private String evaluateExpression(String spelExpression) {
- return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
- }
-
- /**
- * Helper interface that wraps getBean method.
- */
- @FunctionalInterface
- private interface BeanFinder {
- /**
- * Get bean.
- * @return Bean or null if {@link BeansException} was thrown.
- */
- default Object getBean() {
- try {
- return get();
- } catch (BeansException ex) {
- return null;
- }
- }
-
- /**
- * Get bean.
- * @return Bean.
- * @throws BeansException If bean was not found.
- */
- Object get() throws BeansException;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java
deleted file mode 100644
index 4494c14..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.support;
-
-import java.util.Optional;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata22.repository.query.IgniteQuery;
-import org.apache.ignite.springdata22.repository.query.IgniteQueryGenerator;
-import org.apache.ignite.springdata22.repository.query.IgniteRepositoryQuery;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.RepositoryInformation;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.core.support.AbstractEntityInformation;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * Crucial for spring-data functionality class. Create proxies for repositories.
- * <p>
- * Supports multiple Ignite Instances on same JVM.
- * <p>
- * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteRepositoryFactory extends RepositoryFactorySupport {
- /** Spring application expression resolver */
- private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
-
- /** Spring application bean expression context */
- private final BeanExpressionContext beanExpressionContext;
-
- /** Ignite cache proxy instance associated with the current repository. */
- private final IgniteCacheProxy<?, ?> cache;
-
- /** Ignite proxy instance associated with the current repository. */
- private final IgniteProxy ignite;
-
- /**
- * @param ctx Spring Application context.
- * @param repoInterface Repository interface.
- */
- public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
- ignite = ctx.getBean(IgniteProxy.class, repoInterface);
-
- beanExpressionContext = new BeanExpressionContext(
- new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
- null);
-
- RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
-
- String cacheName = evaluateExpression(cfg.cacheName());
-
- Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
- ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
- " annotation to map this repository to the underlying cache.");
-
- cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
-
- if (cache == null) {
- throw new IllegalArgumentException(
- "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
- + ". Please, add a cache configuration to ignite configuration"
- + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
- }
- }
-
- /** {@inheritDoc} */
- @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
- return new AbstractEntityInformation<T, ID>(domainClass) {
- /** {@inheritDoc} */
- @Override public ID getId(T entity) {
- return null;
- }
-
- /** {@inheritDoc} */
- @Override public Class<ID> getIdType() {
- return null;
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
- return IgniteRepositoryImpl.class;
- }
-
- /**
- * Evaluate the SpEL expression
- *
- * @param spelExpression SpEL expression
- * @return the result of execution of the SpEL expression
- */
- private String evaluateExpression(String spelExpression) {
- return (String)resolver.evaluate(spelExpression, beanExpressionContext);
- }
-
- /** {@inheritDoc} */
- @Override protected Object getTargetRepository(RepositoryInformation metadata) {
- return getTargetRepositoryViaReflection(metadata, ignite, cache);
- }
-
- /** {@inheritDoc} */
- @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
- return Optional.of((mtd, metadata, factory, namedQueries) -> {
- final Query annotation = mtd.getAnnotation(Query.class);
- if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
- .dynamicQuery())) {
-
- String qryStr = annotation.value();
-
- boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
- .textQuery());
-
- IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
- !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
- annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
-
- if (key != QueryLookupStrategy.Key.CREATE) {
- return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
- annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
- evaluationContextProvider);
- }
- }
-
- if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
- throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
- + "a query string via org.apache.ignite.springdata22.repository"
- + ".config.Query annotation.");
- }
-
- return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
- cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
- });
- }
-
- /**
- * @param qry Query string.
- * @return {@code true} if query is SqlFieldsQuery.
- */
- public static boolean isFieldQuery(String qry) {
- String qryUpperCase = qry.toUpperCase();
-
- return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
- }
-
- /**
- * Evaluates if the query starts with a clause.<br>
- * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
- *
- * @param qryUpperCase Query string in upper case.
- * @return {@code true} if query is full SQL statement.
- */
- private static boolean isStatement(String qryUpperCase) {
- return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
- // update
- qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
- // delete
- qryUpperCase.matches("^\\s*DELETE\\b.*") ||
- // merge
- qryUpperCase.matches("^\\s*MERGE\\b.*") ||
- // insert
- qryUpperCase.matches("^\\s*INSERT\\b.*");
- }
-
- /**
- * @return Configuration of the specified repository.
- * @throws IllegalArgumentException If no configuration is specified.
- * @see RepositoryConfig
- */
- static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
- RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
-
- Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
- RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
-
- return cfg;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java
deleted file mode 100644
index 4f6b7a9..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.support;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-
-/**
- * Apache Ignite repository factory bean.
- * <p>
- * The {@link org.apache.ignite.springdata22.repository.config.RepositoryConfig} requires to define one of the
- * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
- * <ul/>
- *
- * @param <T> Repository type, {@link IgniteRepository}
- * @param <V> Domain object class.
- * @param <K> Domain object key, super expects {@link Serializable}.
- */
-public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
- extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
- /** */
- private ApplicationContext ctx;
-
- /**
- * @param repoInterface Repository interface.
- */
- protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
- super(repoInterface);
- }
-
- /** {@inheritDoc} */
- @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
- this.ctx = ctx;
- }
-
- /** {@inheritDoc} */
- @Override protected RepositoryFactorySupport createRepositoryFactory() {
- return new IgniteRepositoryFactory(ctx, getObjectType());
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java
deleted file mode 100644
index 67a5b98..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.support;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.cache.Cache;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CachePeekMode;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.context.annotation.Conditional;
-
-/**
- * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
- * {@link IgniteRepositoryFactory}
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Conditional(ConditionFalse.class)
-public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
- /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
- private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
- " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
-
- /**
- * Ignite Cache bound to the repository
- */
- private final IgniteCacheProxy<K, V> cache;
-
- /**
- * Ignite instance bound to the repository
- */
- private final IgniteProxy ignite;
-
- /**
- * Repository constructor.
- *
- * @param ignite the ignite
- * @param cache Initialized cache instance.
- */
- public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
- this.cache = cache;
- this.ignite = ignite;
- }
-
- /** {@inheritDoc} */
- @Override public IgniteCache<K, V> cache() {
- if (cache instanceof IgniteNodeCacheProxy)
- return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
-
- throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
- }
-
- /** {@inheritDoc} */
- @Override public Ignite ignite() {
- if (ignite instanceof IgniteNodeProxy)
- return ((IgniteNodeProxy)ignite).delegate();
-
- throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> S save(K key, S entity) {
- cache.put(key, entity);
-
- return entity;
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
- cache.putAll(entities);
-
- return entities.values();
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
- if (expiryPlc != null)
- cache.withExpiryPolicy(expiryPlc).put(key, entity);
- else
- cache.put(key, entity);
- return entity;
- }
-
- /** {@inheritDoc} */
- @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
- if (expiryPlc != null)
- cache.withExpiryPolicy(expiryPlc).putAll(entities);
- else
- cache.putAll(entities);
- return entities.values();
- }
-
- /**
- * Not implemented.
- */
- @Override public <S extends V> S save(S entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
- }
-
- /**
- * Not implemented.
- */
- @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
- throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public Optional<V> findById(K id) {
- return Optional.ofNullable(cache.get(id));
- }
-
- /** {@inheritDoc} */
- @Override public boolean existsById(K id) {
- return cache.containsKey(id);
- }
-
- /** {@inheritDoc} */
- @Override public Iterable<V> findAll() {
- final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
-
- return new Iterable<V>() {
- /** */
- @Override public Iterator<V> iterator() {
- return new Iterator<V>() {
- /** {@inheritDoc} */
- @Override public boolean hasNext() {
- return iter.hasNext();
- }
-
- /** {@inheritDoc} */
- @Override public V next() {
- return iter.next().getValue();
- }
-
- /** {@inheritDoc} */
- @Override public void remove() {
- iter.remove();
- }
- };
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override public Iterable<V> findAllById(Iterable<K> ids) {
- if (ids instanceof Set)
- return cache.getAll((Set<K>)ids).values();
-
- if (ids instanceof Collection)
- return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
-
- TreeSet<K> keys = new TreeSet<>();
-
- for (K id : ids)
- keys.add(id);
-
- return cache.getAll(keys).values();
- }
-
- /** {@inheritDoc} */
- @Override public long count() {
- return cache.size(CachePeekMode.PRIMARY);
- }
-
- /** {@inheritDoc} */
- @Override public void deleteById(K id) {
- cache.remove(id);
- }
-
- /** {@inheritDoc} */
- @Override public void delete(V entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAll(Iterable<? extends V> entities) {
- throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAllById(Iterable<? extends K> ids) {
- if (ids instanceof Set) {
- cache.removeAll((Set<K>)ids);
- return;
- }
-
- if (ids instanceof Collection) {
- cache.removeAll(new HashSet<>((Collection<K>)ids));
- return;
- }
-
- TreeSet<K> keys = new TreeSet<>();
-
- for (K id : ids)
- keys.add(id);
-
- cache.removeAll(keys);
- }
-
- /** {@inheritDoc} */
- @Override public void deleteAll() {
- cache.clear();
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java
deleted file mode 100644
index cc15fc7..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains supporting files required by Spring Data framework.
- */
-package org.apache.ignite.springdata22.repository.support;
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
deleted file mode 100644
index ec2e7ca..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data operation with compound key when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCompoundKeyTest extends IgniteSpringDataCompoundKeyTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(CityRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override protected Ignite ignite() {
- return ctx.getBean("igniteServerNode", Ignite.class);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
deleted file mode 100644
index 226ee9b..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- }
-
- /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
- @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
- GridTestUtils.assertThrows(log,
- () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
- "Query of type TextQuery is not supported by thin client. Check" +
- " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
- " method configuration or use Ignite node instance to connect to the Ignite cluster.");
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
deleted file mode 100644
index 27d3645..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data query operations when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataQueriesSelfTest extends IgniteSpringDataQueriesSelfTest {
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(IgniteClientApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- repo2 = ctx.getBean(PersonSecondRepository.class);
- repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
- for (int i = 0; i < CACHE_SIZE; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
deleted file mode 100644
index d3ccf5e..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.City;
-import org.apache.ignite.springdata.compoundkey.CityKey;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-
-/**
- * Test with using conpoud key in spring-data
- * */
-public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest {
- /** Application context */
- protected static AnnotationConfigApplicationContext ctx;
-
- /** City repository */
- protected static CityRepository repo;
-
- /** Cache name */
- private static final String CACHE_NAME = "City";
-
- /** Cities count */
- private static final int TOTAL_COUNT = 5;
-
- /** Count Afganistan cities */
- private static final int AFG_COUNT = 4;
-
- /** Kabul identifier */
- private static final int KABUL_ID = 1;
-
- /** Quandahar identifier */
- private static final int QUANDAHAR_ID = 2;
-
- /** Afganistan county code */
- private static final String AFG = "AFG";
-
- /** test city Kabul */
- protected static final City KABUL = new City("Kabul", "Kabol", 1780000);
-
- /** test city Quandahar */
- private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
-
- /**
- * Performs context initialization before tests.
- */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
- ctx.register(CompoundKeyApplicationConfiguration.class);
- ctx.refresh();
-
- repo = ctx.getBean(CityRepository.class);
- }
-
- /**
- * Load data
- * */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- loadData();
-
- assertEquals(getTotalCount(), repo.count());
- }
-
- /**
- * Clear data
- * */
- @Override protected void afterTest() throws Exception {
- repo.deleteAll();
-
- assertEquals(0, repo.count());
-
- super.afterTest();
- }
-
- /**
- * Performs context destroy after tests.
- */
- @Override protected void afterTestsStopped() {
- ctx.close();
- }
-
- /** Load data. */
- public void loadData() throws Exception {
- Ignite ignite = ignite();
-
- if (ignite.cacheNames().contains(CACHE_NAME))
- ignite.destroyCache(CACHE_NAME);
-
- try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:" + CLI_CONN_PORT + '/')) {
- Statement st = conn.createStatement();
-
- st.execute("DROP TABLE IF EXISTS City");
- st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\"");
- st.execute("SET STREAMING ON;");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)");
- st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)");
- }
- }
-
- /** Test */
- @Test
- public void test() {
- assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
- assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
- assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
- }
-
- /** Test. */
- @Test
- public void deleteAllById() {
- Set<CityKey> keys = new HashSet<>();
- keys.add(new CityKey(1, "AFG"));
- keys.add(new CityKey(2, "AFG"));
- keys.add(new CityKey(3, "AFG"));
- keys.add(new CityKey(4, "AFG"));
- keys.add(new CityKey(5, "NLD"));
-
- repo.deleteAllById(keys);
- assertEquals(0, repo.count());
- }
-
- /** */
- protected Ignite ignite() {
- return ctx.getBean(Ignite.class);
- }
-
- /** Total count of entries after load data. */
- protected int getTotalCount() {
- return TOTAL_COUNT;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
deleted file mode 100644
index e11c1c0..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
-import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE;
-
-/** Tests Spring Data repository cluster connection configurations. */
-public class IgniteSpringDataConnectionConfigurationTest extends GridCommonAbstractTest {
- /** */
- private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
- /** */
- private static final String CACHE_NAME = "PersonCache";
-
- /** */
- private static final int CLI_CONN_PORT = 10810;
-
- /** */
- private static final String CLI_NAME = "cli-node";
-
- /** */
- private static final String SRV_NAME = "srv-node";
-
- /** */
- private static final String LOCAL_HOST = "127.0.0.1";
-
- /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithIgniteConfiguration() {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
- assertClientNodeIsStopped();
- }
-
- /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithClientConfiguration() {
- checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
- }
-
- /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteInstanceParameter() {
- checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteClientInstanceParameter() {
- checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgnitClientConfigurationParameter() {
- checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
- @Test
- public void testRepositoryWithoutIgniteConfigurationParameter() {
- checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
- }
-
- /**
- * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
- * used to access the Ignite cluster.
- */
- @Test
- public void testRepositoryWithExistingIgniteInstance() throws Exception {
- try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
- assertNotNull(Ignition.ignite(CLI_NAME));
- }
- }
-
- /** Tests repository configuration in case specified cache name is invalid. */
- @Test
- public void testRepositoryWithInvalidCacheNameConfiguration() {
- try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
- ctx.register(InvalidCacheNameApplication.class);
-
- assertThrowsAnyCause(log,
- () -> {
- ctx.refresh();
-
- return null;
- },
- IllegalArgumentException.class,
- "Cache 'invalidCache' not found for repository interface" +
- " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
- " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
- " org.apache.ignite.springdata22.repository.config.RepositoryConfig annotation.");
- }
-
- assertClientNodeIsStopped();
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- super.afterTest();
-
- grid(SRV_NAME).cache(CACHE_NAME).clear();
- }
-
- /** */
- private void assertClientNodeIsStopped() {
- assertFalse(Ignition.allGrids().stream().map(Ignite::name).anyMatch(CLI_NAME::equals));
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- startGrid(getIgniteConfiguration(SRV_NAME, false));
- }
-
- /**
- * Checks that repository created based on specified Spring application configuration is properly initialized and
- * got access to the Ignite cluster.
- */
- private void checkRepositoryConfiguration(
- Class<?> cfgCls,
- Class<? extends IgniteRepository<Object, Serializable>> repoCls
- ) {
- try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
- ctx.register(cfgCls);
- ctx.refresh();
-
- IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
-
- IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
-
- assertEquals(0, repo.count());
- assertEquals(0, cache.size());
-
- int key = 0;
-
- repo.save(key, "1");
-
- assertEquals(1, repo.count());
- assertNotNull(cache.get(key));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
- public static class InvalidCacheNameApplication {
- /** Ignite configuration bean. */
- @Bean
- public IgniteConfiguration igniteConfiguration() {
- return getIgniteConfiguration(CLI_NAME, true);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
- public static class IgniteConfigurationApplication {
- /** Ignite configuration bean. */
- @Bean
- public IgniteConfiguration igniteConfiguration() {
- return getIgniteConfiguration(CLI_NAME, true);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case {@link ClientConfiguration} is used
- * for accessing the cluster.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
- public static class ClientConfigurationApplication {
- /** Ignite client configuration bean. */
- @Bean
- public ClientConfiguration clientConfiguration() {
- return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if Ignite bean name was not provided
- * through {@link RepositoryConfig#igniteInstance()} ()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteBeanApplication {
- /** Ignite bean. */
- @Bean
- public Ignite someIgnite() {
- return Ignition.start(getIgniteConfiguration("test", false));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
- * through {@link RepositoryConfig#igniteInstance()} ()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteClientBeanApplication {
- /** Ignite client bean. */
- @Bean
- public IgniteClient someIgnite() {
- return Ignition.startClient(new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT));
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
- * through {@link RepositoryConfig#igniteCfg()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteClientConfigurationBeanApplication {
- /** Ignite client configuration bean. */
- @Bean
- public ClientConfiguration someCfg() {
- return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
- }
- }
-
- /**
- * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
- * through {@link RepositoryConfig#igniteCfg()}.
- */
- @Configuration
- @EnableIgniteRepositories(
- considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
- )
- public static class DefaultIgniteConfigurationBeanApplication {
- /** Ignite client configuration bean. */
- @Bean
- public IgniteConfiguration someCfg() {
- return getIgniteConfiguration("test", false);
- }
- }
-
- /** Repository for testing configuration approach through default ignite beans. */
- @RepositoryConfig(cacheName = "PersonCache")
- public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
- @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
- public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
- @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
- public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
- @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
- public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
- // No-op.
- }
-
- /** */
- private static IgniteConfiguration getIgniteConfiguration(String name, boolean clientMode) {
- return new IgniteConfiguration()
- .setIgniteInstanceName(name)
- .setClientMode(clientMode)
- .setLocalHost(LOCAL_HOST)
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER))
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
- .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME));
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
deleted file mode 100644
index a543044..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.TreeSet;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.FullNameProjection;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * CRUD tests.
- */
-public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
- /** Repository. */
- protected static PersonRepository repo;
-
- /** Context. */
- protected static AnnotationConfigApplicationContext ctx;
-
- /** Number of entries to store */
- private static int CACHE_SIZE = 1000;
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(ApplicationConfiguration.class);
-
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- fillInRepository();
-
- assertEquals(CACHE_SIZE, repo.count());
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- repo.deleteAll();
-
- assertEquals(0, repo.count());
-
- super.afterTest();
- }
-
- /** */
- private void fillInRepository() {
- for (int i = 0; i < CACHE_SIZE - 5; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
-
- repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTestsStopped() throws Exception {
- ctx.destroy();
- }
-
- /** */
- @Test
- public void testPutGet() {
- Person person = new Person("some_name", "some_surname");
-
- int id = CACHE_SIZE + 1;
-
- assertEquals(person, repo.save(id, person));
-
- assertTrue(repo.existsById(id));
-
- assertEquals(person, repo.findById(id).get());
-
- try {
- repo.save(person);
-
- fail("Managed to save a Person without ID");
- }
- catch (UnsupportedOperationException e) {
- //excepted
- }
- }
-
- /** */
- @Test
- public void testPutAllGetAll() {
- LinkedHashMap<Integer, Person> map = new LinkedHashMap<>();
-
- for (int i = CACHE_SIZE; i < CACHE_SIZE + 50; i++)
- map.put(i, new Person("some_name" + i, "some_surname" + i));
-
- Iterator<Person> persons = repo.save(map).iterator();
-
- assertEquals(CACHE_SIZE + 50, repo.count());
-
- Iterator<Person> origPersons = map.values().iterator();
-
- while (persons.hasNext())
- assertEquals(origPersons.next(), persons.next());
-
- try {
- repo.saveAll(map.values());
-
- fail("Managed to save a list of Persons with ids");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
-
- persons = repo.findAllById(map.keySet()).iterator();
-
- int counter = 0;
-
- while (persons.hasNext()) {
- persons.next();
- counter++;
- }
-
- assertEquals(map.size(), counter);
- }
-
- /** */
- @Test
- public void testGetAll() {
- assertEquals(CACHE_SIZE, repo.count());
-
- Iterator<Person> persons = repo.findAll().iterator();
-
- int counter = 0;
-
- while (persons.hasNext()) {
- persons.next();
- counter++;
- }
-
- assertEquals(repo.count(), counter);
- }
-
- /** */
- @Test
- public void testDelete() {
- assertEquals(CACHE_SIZE, repo.count());
-
- repo.deleteById(0);
-
- assertEquals(CACHE_SIZE - 1, repo.count());
- assertEquals(Optional.empty(),repo.findById(0));
-
- try {
- repo.delete(new Person("", ""));
-
- fail("Managed to delete a Person without id");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /** */
- @Test
- public void testDeleteSet() {
- assertEquals(CACHE_SIZE, repo.count());
-
- TreeSet<Integer> ids = new TreeSet<>();
-
- for (int i = 0; i < CACHE_SIZE / 2; i++)
- ids.add(i);
-
- repo.deleteAllById(ids);
-
- assertEquals(CACHE_SIZE / 2, repo.count());
-
- try {
- ArrayList<Person> persons = new ArrayList<>();
-
- for (int i = 0; i < 3; i++)
- persons.add(new Person(String.valueOf(i), String.valueOf(i)));
-
- repo.deleteAll(persons);
-
- fail("Managed to delete Persons without ids");
- }
- catch (UnsupportedOperationException e) {
- //expected
- }
- }
-
- /** */
- @Test
- public void testDeleteAll() {
- assertEquals(CACHE_SIZE, repo.count());
-
- repo.deleteAll();
-
- assertEquals(0, repo.count());
- }
-
- /**
- * Delete existing record.
- */
- @Test
- public void testDeleteByFirstName() {
- assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
-
- long cnt = repo.deleteByFirstName("uniquePerson");
-
- assertEquals(1, cnt);
- }
-
- /**
- * Delete NON existing record.
- */
- @Test
- public void testDeleteExpression() {
- long cnt = repo.deleteByFirstName("880");
-
- assertEquals(0, cnt);
- }
-
- /**
- * Delete Multiple records due to where.
- */
- @Test
- public void testDeleteExpressionMultiple() {
- long count = repo.countByFirstName("nonUniquePerson");
- long cnt = repo.deleteByFirstName("nonUniquePerson");
-
- assertEquals(cnt, count);
- }
-
- /**
- * Remove should do the same than Delete.
- */
- @Test
- public void testRemoveExpression() {
- repo.removeByFirstName("person3f");
-
- long count = repo.count();
- assertEquals(CACHE_SIZE - 1, count);
- }
-
- /**
- * Delete unique record using lower case key word.
- */
- @Test
- public void testDeleteQuery() {
- repo.deleteBySecondNameLowerCase("uniqueLastName");
-
- long countAfter = repo.count();
- assertEquals(CACHE_SIZE - 1, countAfter);
- }
-
- /**
- * Try to delete with a wrong @Query.
- */
- @Test
- public void testWrongDeleteQuery() {
- long countBefore = repo.countByFirstNameLike("person3f");
-
- try {
- repo.deleteWrongByFirstNameQuery("person3f");
- }
- catch (Exception e) {
- //expected
- }
-
- long countAfter = repo.countByFirstNameLike("person3f");
- assertEquals(countBefore, countAfter);
- }
-
- /**
- * Update with a @Query a record.
- */
- @Test
- public void testUpdateQueryMixedCase() {
- final String newSecondName = "updatedUniqueSecondName";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<Person> person = repo.findByFirstName("uniquePerson");
- assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
- }
-
- /**
- * Update with a @Query a record
- */
- @Test
- public void testUpdateQueryMixedCaseProjection() {
- final String newSecondName = "updatedUniqueSecondName1";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-
- List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
- assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
- final String newSecondName = "updatedUniqueSecondName2";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
- assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
-
- FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
- assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
- final String newSecondName = "updatedUniqueSecondName3";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
- final String newSecondName = "updatedUniqueSecondName4";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
- final String newSecondName = "updatedUniqueSecondName5";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
- }
-
- /** */
- @Test
- public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
- final String newSecondName = "updatedUniqueSecondName6";
- int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
- assertEquals(1, cnt);
-
- List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
- assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
- assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
- }
-
- /**
- * Update with a wrong @Query
- */
- @Test
- public void testWrongUpdateQuery() {
- final String newSecondName = "updatedUniqueSecondName";
- int rowsUpdated = 0;
-
- try {
- rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
- }
- catch (Exception ignored) {
- //expected
- }
-
- assertEquals(0, rowsUpdated);
-
- List<Person> person = repo.findByFirstName("uniquePerson");
- assertEquals(person.get(0).getSecondName(), "uniqueLastName");
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
deleted file mode 100644
index 19a9f63..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.cache.Cache;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.Sort;
-
-/**
- *
- */
-public class IgniteSpringDataQueriesSelfTest extends GridCommonAbstractTest {
- /** Repository. */
- protected static PersonRepository repo;
-
- /** Repository 2. */
- protected static PersonSecondRepository repo2;
-
- /**
- * Repository Ignite Instance cluster TWO.
- */
- protected static PersonRepositoryOtherIgniteInstance repoTWO;
-
- /** Context. */
- protected static AnnotationConfigApplicationContext ctx;
-
- /**
- * Number of entries to store
- */
- protected static int CACHE_SIZE = 1000;
-
- /**
- * Performs context initialization before tests.
- */
- @Override protected void beforeTestsStarted() throws Exception {
- super.beforeTestsStarted();
-
- ctx = new AnnotationConfigApplicationContext();
-
- ctx.register(ApplicationConfiguration.class);
-
- ctx.refresh();
-
- repo = ctx.getBean(PersonRepository.class);
- repo2 = ctx.getBean(PersonSecondRepository.class);
- // repository on another ignite instance (and another cluster)
- repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
- for (int i = 0; i < CACHE_SIZE; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
- }
-
- /**
- * Performs context destroy after tests.
- */
- @Override protected void afterTestsStopped() throws Exception {
- ctx.destroy();
- }
-
- /** */
- @Test
- public void testExplicitQuery() {
- List<Person> persons = repo.simpleQuery("person4a");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("person4a", person.getFirstName());
- }
-
- /** */
- @Test
- public void testExplicitQueryTWO() {
- List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("TWOperson4a", person.getFirstName());
- }
-
- /** */
- @Test
- public void testEqualsPart() {
- List<Person> persons = repo.findByFirstName("person4e");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("person4e", person.getFirstName());
- }
-
- /** */
- @Test
- public void testEqualsPartTWO() {
- List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertEquals("TWOperson4e", person.getFirstName());
- }
-
- /** */
- @Test
- public void testContainingPart() {
- List<Person> persons = repo.findByFirstNameContaining("person4");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertTrue(person.getFirstName().startsWith("person4"));
- }
-
- /** */
- @Test
- public void testContainingPartTWO() {
- List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
-
- assertFalse(persons.isEmpty());
-
- for (Person person : persons)
- assertTrue(person.getFirstName().startsWith("TWOperson4"));
- }
-
- /** */
- @Test
- public void testTopPart() {
- Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
-
- Iterator<Person> iter = top.iterator();
-
- Person person = iter.next();
-
- assertFalse(iter.hasNext());
-
- assertTrue(person.getFirstName().startsWith("person4"));
- }
-
- /** */
- @Test
- public void testTopPartTWO() {
- Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
-
- Iterator<Person> iter = top.iterator();
-
- Person person = iter.next();
-
- assertFalse(iter.hasNext());
-
- assertTrue(person.getFirstName().startsWith("TWOperson4"));
- }
-
- /** */
- @Test
- public void testLikeAndLimit() {
- Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
-
- int cnt = 0;
-
- for (Person next : like) {
- assertTrue(next.getFirstName().contains("person"));
-
- cnt++;
- }
-
- assertEquals(10, cnt);
- }
-
- /** */
- @Test
- public void testLikeAndLimitTWO() {
- Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
-
- int cnt = 0;
-
- for (Person next : like) {
- assertTrue(next.getFirstName().contains("TWOperson"));
-
- cnt++;
- }
-
- assertEquals(10, cnt);
- }
-
- /** */
- @Test
- public void testCount() {
- int cnt = repo.countByFirstNameLike("person");
-
- assertEquals(1000, cnt);
- }
-
- /** */
- @Test
- public void testCountTWO() {
- int cnt = repoTWO.countByFirstNameLike("TWOperson");
-
- assertEquals(1000, cnt);
- }
-
- /** */
- @Test
- public void testCount2() {
- int cnt = repo.countByFirstNameLike("person4");
-
- assertTrue(cnt < 1000);
- }
-
- /** */
- @Test
- public void testCount2TWO() {
- int cnt = repoTWO.countByFirstNameLike("TWOperson4");
-
- assertTrue(cnt < 1000);
- }
-
- /** */
- @Test
- public void testPageable() {
- PageRequest pageable = PageRequest.of(1, 5, Sort.Direction.DESC, "firstName");
-
- HashSet<String> firstNames = new HashSet<>();
-
- List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", pageable);
-
- assertEquals(5, pageable1.size());
-
- for (Person person : pageable1) {
- firstNames.add(person.getFirstName());
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
- }
-
- List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", pageable.next());
-
- assertEquals(5, pageable2.size());
-
- for (Person person : pageable2) {
- firstNames.add(person.getFirstName());
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
- }
-
- assertEquals(10, firstNames.size());
- }
-
- /** */
- @Test
- public void testAndAndOr() {
- int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
-
- int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", "lastName1");
-
- assertTrue(cntAnd <= cntOr);
- }
-
- /** */
- @Test
- public void testQueryWithSort() {
- List<Person> persons = repo.queryWithSort("^[a-z]+$", Sort.by(Sort.Direction.DESC, "secondName"));
-
- Person previous = persons.get(0);
-
- for (Person person : persons) {
- assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
- previous = person;
- }
- }
-
- /** */
- @Test
- public void testQueryWithPaging() {
- List<Person> persons = repo.queryWithPageable("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
-
- assertEquals(7, persons.size());
-
- Person previous = persons.get(0);
-
- for (Person person : persons) {
- assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
- assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
- previous = person;
- }
- }
-
- /** */
- @Test
- public void testQueryFields() {
- List<String> persons = repo.selectField("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
-
- assertEquals(7, persons.size());
- }
-
- /** */
- @Test
- public void testFindCacheEntries() {
- List<Cache.Entry<Integer, Person>> cacheEntries = repo.findBySecondNameLike("stName1");
-
- assertFalse(cacheEntries.isEmpty());
-
- for (Cache.Entry<Integer, Person> entry : cacheEntries)
- assertTrue(entry.getValue().getSecondName().contains("stName1"));
- }
-
- /** */
- @Test
- public void testFindOneCacheEntry() {
- Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
-
- assertNotNull(cacheEntry);
-
- assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
- }
-
- /** */
- @Test
- public void testFindOneValue() {
- PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
-
- assertNotNull(person);
-
- assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
- }
-
- /** */
- @Test
- public void testSelectSeveralFields() {
- List<List> lists = repo.selectSeveralField("^[a-z]+$", PageRequest.of(2, 6));
-
- assertEquals(6, lists.size());
-
- for (List list : lists) {
- assertEquals(2, list.size());
-
- assertTrue(list.get(0) instanceof Integer);
- }
- }
-
- /** */
- @Test
- public void testCountQuery() {
- int cnt = repo.countQuery(".*");
-
- assertEquals(256, cnt);
- }
-
- /** */
- @Test
- public void testSliceOfCacheEntries() {
- Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", PageRequest.of(3, 4));
-
- assertEquals(4, slice.getSize());
-
- for (Cache.Entry<Integer, Person> entry : slice)
- assertFalse("lastName18".equals(entry.getValue().getSecondName()));
- }
-
- /** */
- @Test
- public void testSliceOfLists() {
- Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", PageRequest.of(0, 3));
-
- assertEquals(3, lists.getSize());
-
- for (List list : lists) {
- assertEquals(2, list.size());
-
- assertTrue(list.get(0) instanceof Integer);
- }
- }
-
- /** Tests conversion of SQL select query result to domain entity objects. */
- @Test
- public void testRowToEntityConversion() {
- Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
-
- Set<Person> exp = new HashSet<>();
-
- repo.findAll().forEach(exp::add);
-
- assertEquals(exp, res);
- }
-
- /**
- * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
- * of domain entity class.
- */
- @Test
- public void testIncompleteRowToEntityConversion() {
- Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
-
- Set<Person> exp = new HashSet<>();
-
- repo.findAll().forEach(p -> {
- p.setSecondName(null);
-
- exp.add(p);
- });
-
- assertEquals(exp, res);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
deleted file mode 100644
index e86a575..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.Objects;
-
-/**
- * Value-class
- * */
-public class City {
- /** City name */
- private String name;
-
- /** City district */
- private String district;
-
- /** City population */
- private int population;
-
- /**
- * @param name city name
- * @param district city district
- * @param population city population
- * */
- public City(String name, String district, int population) {
- this.name = name;
- this.district = district;
- this.population = population;
- }
-
- /**
- * @return city name
- * */
- public String getName() {
- return name;
- }
-
- /**
- * @param name city name
- * */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @return city district
- * */
- public String getDistrict() {
- return district;
- }
-
- /**
- * @param district city district
- * */
- public void setDistrict(String district) {
- this.district = district;
- }
-
- /**
- * @return city population
- * */
- public int getPopulation() {
- return population;
- }
-
- /**
- * @param population city population
- * */
- public void setPopulation(int population) {
- this.population = population;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return name + " | " + district + " | " + population;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- City city = (City)o;
-
- return
- Objects.equals(this.name, city.name) &&
- Objects.equals(this.district, city.district) &&
- this.population == city.population;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(name, district, population);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
deleted file mode 100644
index 88226fe..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.io.Serializable;
-import java.util.Objects;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/** Compound key for city class */
-public class CityKey implements Serializable {
- /** city identifier */
- private int ID;
-
- /** affinity key countrycode */
- @AffinityKeyMapped
- private String COUNTRYCODE;
-
- /**
- * @param id city identifier
- * @param countryCode city countrycode
- * */
- public CityKey(int id, String countryCode) {
- this.ID = id;
- this.COUNTRYCODE = countryCode;
- }
-
- /**
- * @return city id
- * */
- public int getId() {
- return ID;
- }
-
- /**
- * @return countrycode
- * */
- public String getCountryCode() {
- return COUNTRYCODE;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- CityKey key = (CityKey)o;
-
- return ID == key.ID &&
- COUNTRYCODE.equals(key.COUNTRYCODE);
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(ID, COUNTRYCODE);
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return ID + " | " + COUNTRYCODE;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
deleted file mode 100644
index ab745e7..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.stereotype.Repository;
-
-/** City repository */
-@Repository
-@RepositoryConfig(cacheName = "City", autoCreateCache = true)
-public interface CityRepository extends IgniteRepository<City, CityKey> {
- /**
- * Find city by id
- * @param id city identifier
- * @return city
- * */
- public City findById(int id);
-
- /**
- * Find all cities by coutrycode
- * @param cc coutrycode
- * @return list of cache enrties CityKey -> City
- * */
- public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc);
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
deleted file mode 100644
index 2d472a2..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Spring application configuration
- * */
-@Configuration
-@EnableIgniteRepositories
-public class CompoundKeyApplicationConfiguration {
- /** */
- public static final int CLI_CONN_PORT = 10810;
-
- /**
- * Ignite instance bean
- * */
- @Bean
- public Ignite igniteInstance() {
- return Ignition.start(new IgniteConfiguration()
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT)));
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
deleted file mode 100644
index 1443d5d..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.spel.spi.EvaluationContextExtension;
-
-/** */
-@Configuration
-@EnableIgniteRepositories
-public class ApplicationConfiguration {
- /** */
- public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
-
- /** */
- public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
-
- /**
- * The bean with cache names
- */
- @Bean
- public CacheNamesBean cacheNames() {
- CacheNamesBean bean = new CacheNamesBean();
-
- bean.setPersonCacheName("PersonCache");
-
- return bean;
- }
-
- /** */
- @Bean
- public EvaluationContextExtension sampleSpELExtension() {
- return new SampleEvaluationContextExtension();
- }
-
- /** */
- @Bean(value = "sampleExtensionBean")
- public SamplePassParamExtension sampleExtensionBean() {
- return new SamplePassParamExtension();
- }
-
- /**
- * Ignite instance bean - no instance name provided on RepositoryConfig
- */
- @Bean
- public Ignite igniteInstance() {
- IgniteConfiguration cfg = new IgniteConfiguration();
-
- cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
-
- CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
- ccfg.setIndexedTypes(Integer.class, Person.class);
-
- cfg.setCacheConfiguration(ccfg);
-
- TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
- spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
- cfg.setDiscoverySpi(spi);
-
- return Ignition.start(cfg);
- }
-
- /**
- * Ignite instance bean with not default name
- */
- @Bean
- public Ignite igniteInstanceTWO() {
- IgniteConfiguration cfg = new IgniteConfiguration();
-
- cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
-
- CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
- ccfg.setIndexedTypes(Integer.class, Person.class);
-
- cfg.setCacheConfiguration(ccfg);
-
- TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
- spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
- cfg.setDiscoverySpi(spi);
-
- return Ignition.start(cfg);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
deleted file mode 100644
index 6185744..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-/**
- * The bean with cache names.
- */
-public class CacheNamesBean {
- /** */
- private String personCacheName;
-
- /**
- * Get name of cache for persons.
- *
- * @return Name of cache.
- */
- public String getPersonCacheName() {
- return personCacheName;
- }
-
- /**
- * @param personCacheName Name of cache.
- */
- public void setPersonCacheName(String personCacheName) {
- this.personCacheName = personCacheName;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
deleted file mode 100644
index 23f8f8e..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import org.springframework.beans.factory.annotation.Value;
-
-/**
- * Advanced SpEl Expressions into projection
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public interface FullNameProjection {
- /**
- * Sample of using SpEL expression
- * @return
- */
- @Value("#{target.firstName + ' ' + target.secondName}")
- String getFullName();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
deleted file mode 100644
index ad255d0..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.spel.spi.EvaluationContextExtension;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
-
-/** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
-@Configuration
-@EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
-public class IgniteClientApplicationConfiguration {
- /** Test cache name. */
- public static final String CACHE_NAME = "PersonCache";
-
- /** */
- @Bean
- public CacheNamesBean cacheNames() {
- CacheNamesBean bean = new CacheNamesBean();
-
- bean.setPersonCacheName(CACHE_NAME);
-
- return bean;
- }
-
- /** */
- @Bean
- public EvaluationContextExtension sampleSpELExtension() {
- return new SampleEvaluationContextExtension();
- }
-
- /** */
- @Bean(value = "sampleExtensionBean")
- public SamplePassParamExtension sampleExtensionBean() {
- return new SamplePassParamExtension();
- }
-
- /** */
- @Bean
- public Ignite igniteServerNode() {
- return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
- }
-
- /** */
- @Bean
- public Ignite igniteSecondServerNode() {
- return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
- }
-
- /** Ignite client instance bean with default name. */
- @Bean
- public IgniteClient igniteInstance() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
- .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
- }
-
- /** Ignite client instance bean with non-default name. */
- @Bean
- public IgniteClient igniteInstanceTWO() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
- }
-
- /** */
- private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
- return new IgniteConfiguration()
- .setIgniteInstanceName(igniteInstanceName)
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
- .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
- .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
deleted file mode 100644
index 62c3054..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Date;
-import java.util.Objects;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * DTO class.
- */
-public class Person {
- /** First name. */
- @QuerySqlField(index = true)
- @QueryTextField
- private String firstName;
-
- /** Second name. */
- @QuerySqlField(index = true)
- private String secondName;
-
- /** Birthday. */
- @QuerySqlField
- private Date birthday;
-
- /**
- * @param firstName First name.
- * @param secondName Second name.
- */
- public Person(String firstName, String secondName) {
- this.firstName = firstName;
- this.secondName = secondName;
- birthday = new Date();
- }
-
- /**
- * @return First name.
- */
- public String getFirstName() {
- return firstName;
- }
-
- /**
- * @param firstName First name.
- */
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
-
- /**
- * @return Second name.
- */
- public String getSecondName() {
- return secondName;
- }
-
- /**
- * @param secondName Second name.
- */
- public void setSecondName(String secondName) {
- this.secondName = secondName;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Person{" +
- "firstName='" + firstName + '\'' +
- ", secondName='" + secondName + '\'' +
- ", birthday='" + birthday + '\'' +
- '}';
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (o == null || getClass() != o.getClass())
- return false;
-
- Person person = (Person)o;
-
- return Objects.equals(firstName, person.firstName) &&
- Objects.equals(secondName, person.secondName) &&
- Objects.equals(birthday, person.birthday);
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return Objects.hash(firstName, secondName, birthday);
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
deleted file mode 100644
index 689f856..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-
-/**
- *
- */
-@RepositoryConfig(cacheName = "#{cacheNames.personCacheName}")
-public interface PersonExpressionRepository extends IgniteRepository<Person, Integer> {
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
deleted file mode 100644
index 2537c57..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.io.Serializable;
-
-/**
- * Compound key.
- */
-public class PersonKey implements Serializable {
- /** */
- private int id1;
-
- /** */
- private int id2;
-
- /**
- * @param id1 ID1.
- * @param id2 ID2.
- */
- public PersonKey(int id1, int id2) {
- this.id1 = id1;
- this.id2 = id2;
- }
-
- /**
- * @return ID1
- */
- public int getId1() {
- return id1;
- }
-
- /**
- * @return ID1
- */
- public int getId2() {
- return id1;
- }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
deleted file mode 100644
index a187a08..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import org.springframework.beans.factory.annotation.Value;
-
-/**
- * Advanced SpEl Expressions into projection
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public interface PersonProjection {
- /** */
- String getFirstName();
-
- /**
- * Sample of using registered spring bean into SpEL expression
- * @return
- */
- @Value("#{@sampleExtensionBean.transformParam(target.firstName)}")
- String getFirstNameTransformed();
-
- /**
- * Sample of using SpEL expression
- * @return
- */
- @Value("#{target.firstName + ' ' + target.secondName}")
- String getFullName();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
deleted file mode 100644
index 4fd3e07..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ /dev/null
@@ -1,159 +0,0 @@
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Integer> {
- /** */
- public List<Person> findByFirstName(String val);
-
- /** */
- @Query("firstName = ?")
- public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
- /** */
- @Query("firstName = :firstname")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- /** */
- @Query("firstName = :firstname")
- public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
- /** */
- @Query("firstName = :firstname")
- public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
- /** */
- @Query("firstName = ?#{[1]}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
- /** */
- @Query(textQuery = true, value = "#{#firstname}", limit = 2)
- public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
- @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
- @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
- public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
- /** */
- public List<Person> findByFirstNameContaining(String val);
-
- /** */
- public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
- /** */
- public Collection<Person> findTopByFirstNameContaining(String val);
-
- /** */
- public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
- /** */
- public int countByFirstName(String val);
-
- /** */
- public int countByFirstNameLike(String val);
-
- /** */
- public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
- /** */
- public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
- /** */
- public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
- /** */
- public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
- /** */
- public PersonProjection findTopBySecondNameStartingWith(String val);
-
- /** */
- @Query("firstName = ?")
- public List<Person> simpleQuery(String val);
-
- /** */
- @Query("firstName REGEXP ?")
- public List<Person> queryWithSort(String val, Sort sort);
-
- /** */
- @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
- public List<Person> queryWithPageable(String val, Pageable pageable);
-
- /** */
- @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
- public List<String> selectField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
- public List<List> selectSeveralField(String val, Pageable pageable);
-
- /** */
- @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
- public int countQuery(String val);
-
- /** Top 3 query */
- public List<Person> findTop3ByFirstName(String val);
-
- /** Delete query */
- public long deleteByFirstName(String firstName);
-
- /** Remove Query */
- public List<Person> removeByFirstName(String firstName);
-
- /** Delete using @Query with keyword in lower-case */
- @Query("delete FROM Person WHERE secondName = ?")
- public void deleteBySecondNameLowerCase(String secondName);
-
- /** Delete using @Query but with errors on the query */
- @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public void deleteWrongByFirstNameQuery(String firstName);
-
- /** Update using @Query with keyword in mixed-case */
- @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
- public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
- /** Update using @Query but with errors on the query */
- @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
- public int setWrongFixedSecondName(String secondName, String firstName);
-
- /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
- @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
- public List<Person> queryWithRowToEntityConversion();
-
- /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
- @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
- public List<Person> queryWithIncompleteRowToEntityConversion();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
deleted file mode 100644
index 97b0b5f..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
-public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
deleted file mode 100644
index 24f1c61..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.data.domain.AbstractPageRequest;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
- /** */
- public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String val, PageRequest pageReq);
-
- /** */
- @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
- public Slice<List> querySliceOfList(String val, AbstractPageRequest pageReq);
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java
deleted file mode 100644
index 86f97b2..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.testsuites;
-
-import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundExtendedKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Ignite Spring Data 2.2 test suite.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- IgniteSpringDataCrudSelfTest.class,
- IgniteSpringDataQueriesSelfTest.class,
- IgniteSpringDataCrudSelfExpressionTest.class,
- IgniteSpringDataCompoundKeyTest.class,
- IgniteSpringDataCompoundExtendedKeyTest.class,
- IgniteSpringDataConnectionConfigurationTest.class,
- IgniteClientSpringDataCrudSelfTest.class,
- IgniteClientSpringDataQueriesSelfTest.class,
- IgniteClientSpringDataCompoundKeyTest.class
-})
-public class IgniteSpringData22TestSuite {
-}
diff --git a/modules/spring-data-ext/README.txt b/modules/spring-data-ext/README.txt
index eb7aad9..6d5e0e6 100644
--- a/modules/spring-data-ext/README.txt
+++ b/modules/spring-data-ext/README.txt
@@ -3,7 +3,22 @@
Apache Ignite Spring Data extension provides an integration with Spring Data framework.
-Importing Spring Data Module In Maven Project
+Main features:
+
+- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
+- Supports query tuning parameters in @Query annotation
+- Supports projections
+- Supports Page and Stream responses
+- Supports Sql Fields Query resultset transformation into the domain entity
+- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
+- Supports advanced parameter binding and SpEL expressions into SQL queries:
+- Template variables:
+ - #entityName - the simple class name of the domain entity
+- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
+- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
+- Supports SpEL expressions into Text queries (TextQuery).
+
+Importing Spring Data extension In Maven Project
----------------------------------------
If you are using Maven to manage dependencies of your project, you can add Spring Data extension
diff --git a/modules/spring-data-2.0-ext/examples/config/example-default.xml b/modules/spring-data-ext/examples/config/example-default.xml
similarity index 100%
rename from modules/spring-data-2.0-ext/examples/config/example-default.xml
rename to modules/spring-data-ext/examples/config/example-default.xml
diff --git a/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml b/modules/spring-data-ext/examples/config/example-spring-data.xml
similarity index 95%
rename from modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
rename to modules/spring-data-ext/examples/config/example-spring-data.xml
index 9f7d674..caaa7f8 100644
--- a/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
+++ b/modules/spring-data-ext/examples/config/example-spring-data.xml
@@ -26,10 +26,10 @@
Use this configuration file when running Spring Data examples.
When starting a standalone node, you need to execute the following command:
- {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-2.2/examples/config/example-spring-data.xml
+ {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-ext/examples/config/example-spring-data.xml
When starting Ignite from Java IDE, pass path to this file to Ignition:
- Ignition.start("modules/spring-data-2.2/examples/config/example-spring-data.xml");
+ Ignition.start("modules/spring-data-ext/examples/config/example-spring-data.xml");
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
diff --git a/modules/spring-data-2.0-ext/examples/pom.xml b/modules/spring-data-ext/examples/pom.xml
similarity index 86%
rename from modules/spring-data-2.0-ext/examples/pom.xml
rename to modules/spring-data-ext/examples/pom.xml
index 72696ee..d29e9f2 100644
--- a/modules/spring-data-2.0-ext/examples/pom.xml
+++ b/modules/spring-data-ext/examples/pom.xml
@@ -32,15 +32,15 @@
<relativePath>../../../parent</relativePath>
</parent>
- <artifactId>ignite-spring-data-2.0-ext-examples</artifactId>
- <version>${ignite-spring-data-2.0-ext.version}</version>
+ <artifactId>ignite-spring-data-ext-examples</artifactId>
+ <version>${ignite-spring-data-ext.version}</version>
<url>http://ignite.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.ignite</groupId>
- <artifactId>ignite-spring-data-2.0-ext</artifactId>
- <version>${ignite-spring-data-2.0-ext.version}</version>
+ <artifactId>ignite-spring-data-ext</artifactId>
+ <version>${ignite-spring-data-ext.version}</version>
</dependency>
<dependency>
@@ -56,6 +56,24 @@
</dependency>
<dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-commons</artifactId>
+ <version>${spring.data-version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${ignite.version}</version>
@@ -66,23 +84,5 @@
</exclusion>
</exclusions>
</dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring-5.0.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring-5.0.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.0.version}</version>
- </dependency>
</dependencies>
</project>
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
similarity index 91%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
index 72d8eaa..8c4f253 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
@@ -15,13 +15,13 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
import org.apache.ignite.Ignition;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
similarity index 86%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
index 24b8bdb..007eefc 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
@@ -15,14 +15,14 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
import java.util.List;
import javax.cache.Cache;
-import org.apache.ignite.springdata22.examples.model.Person;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.examples.model.Person;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.springframework.data.domain.Pageable;
/**
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
similarity index 83%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
index d3ca61e..e1c07ff 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
@@ -15,14 +15,14 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -46,6 +46,6 @@
*/
@Bean
public Ignite igniteInstance() {
- return Ignition.start("modules/spring-data-2.2-ext/examples/config/example-spring-data.xml");
+ return Ignition.start("modules/spring-data-ext/examples/config/example-spring-data.xml");
}
}
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
index f585673..23278e3 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
import java.util.ArrayList;
import java.util.Iterator;
@@ -26,7 +26,7 @@
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.examples.model.Person;
+import org.apache.ignite.springdata.examples.model.Person;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.domain.PageRequest;
@@ -34,7 +34,7 @@
* The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
*
* Additional cluster nodes can be started with special configuration file which
- * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data-2.2/examples/config/example-spring-data.xml'}.
+ * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data/examples/config/example-spring-data.xml'}.
*/
public class SpringDataExample {
/** Spring Application Context. */
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
index 6e00981..2e5c119 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReader;
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
index 12a99fa..5b4082e 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
import java.util.Collection;
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
similarity index 97%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
index 5d16ebd..5b17a56 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
import org.apache.ignite.cache.affinity.AffinityKeyMapped;
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
similarity index 97%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
index d06e05c..51bbb25 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
import java.sql.Timestamp;
import java.util.concurrent.atomic.AtomicLong;
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
similarity index 94%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
index 140ff4e..0dae708 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
/**
* Organization type enum.
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
similarity index 98%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
index e9250be..22d2b6c 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLong;
diff --git a/modules/spring-data-ext/pom.xml b/modules/spring-data-ext/pom.xml
index 854ff5f..da5b1e2 100644
--- a/modules/spring-data-ext/pom.xml
+++ b/modules/spring-data-ext/pom.xml
@@ -84,11 +84,9 @@
</dependency>
<dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <version>${ignite.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>${commons.lang.version}</version>
</dependency>
<dependency>
@@ -100,6 +98,14 @@
<dependency>
<groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${ignite.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${ignite.version}</version>
<scope>test</scope>
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
index 472d2e0..d55cf6a 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
@@ -18,41 +18,92 @@
import java.io.Serializable;
import java.util.Map;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.jetbrains.annotations.Nullable;
import org.springframework.data.repository.CrudRepository;
/**
* Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
+ *
+ * @param <V> the cache value type
+ * @param <K> the cache key type
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
-public interface IgniteRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
+public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
+ /**
+ * Returns the Ignite instance bound to the repository
+ *
+ * @return the Ignite instance bound to the repository
+ */
+ public Ignite ignite();
+
+ /**
+ * Returns the Ignite Cache bound to the repository
+ *
+ * @return the Ignite Cache bound to the repository
+ */
+ public IgniteCache<K, V> cache();
+
/**
* Saves a given entity using provided key.
* </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates
- * IDs (keys) that are not unique cluster wide.
+ * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+ * (keys) that are not unique cluster wide.
*
- * @param key Entity's key.
+ * @param <S> Entity type.
+ * @param key Entity's key.
* @param entity Entity to save.
- * @param <S> Entity type.
* @return Saved entity.
*/
- <S extends T> S save(ID key, S entity);
+ public <S extends V> S save(K key, S entity);
/**
* Saves all given keys and entities combinations.
* </p>
- * It's suggested to use this method instead of default {@link CrudRepository#save(Iterable)} that generates
- * IDs (keys) that are not unique cluster wide.
+ * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+ * (keys) that are not unique cluster wide.
*
+ * @param <S> Type of entities.
* @param entities Map of key-entities pairs to save.
- * @param <S> type of entities.
* @return Saved entities.
*/
- <S extends T> Iterable<S> save(Map<ID, S> entities);
+ public <S extends V> Iterable<S> save(Map<K, S> entities);
+
+ /**
+ * Saves a given entity using provided key with expiry policy
+ * </p>
+ * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+ * (keys) that are not unique cluster wide.
+ *
+ * @param <S> Entity type.
+ * @param key Entity's key.
+ * @param entity Entity to save.
+ * @param expiryPlc ExpiryPolicy to apply, if not null.
+ * @return Saved entity.
+ */
+ public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
+
+ /**
+ * Saves all given keys and entities combinations with expiry policy
+ * </p>
+ * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+ * (keys) that are not unique cluster wide.
+ *
+ * @param <S> Type of entities.
+ * @param entities Map of key-entities pairs to save.
+ * @param expiryPlc ExpiryPolicy to apply, if not null.
+ * @return Saved entities.
+ */
+ public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
/**
* Deletes all the entities for the provided ids.
*
* @param ids List of ids to delete.
*/
- void deleteAll(Iterable<ID> ids);
+ public void deleteAllById(Iterable<? extends K> ids);
+
}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
similarity index 99%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
index f915267..c4d2fd4 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ignite.springdata22.repository.config;
+package org.apache.ignite.springdata.repository.config;
/**
* Runtime Dynamic query configuration.
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
index f73fc3d..fba390b 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
@@ -97,8 +97,8 @@
Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
/**
- * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
- * {@link IgniteRepositoryFactoryBean}.
+ * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
+ * IgniteRepositoryFactoryBean}.
*
* @return {@link FactoryBean} class to be used for each repository instance.
*/
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
index 0f65c32..26b7dc1 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
@@ -17,6 +17,7 @@
package org.apache.ignite.springdata.repository.config;
import java.lang.annotation.Annotation;
+
import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
index 6f21b59..8451118 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.Collections;
+import org.apache.ignite.springdata.proxy.IgniteProxy;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.apache.ignite.springdata.repository.support.IgniteProxyFactory;
import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
@@ -27,6 +28,8 @@
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
+import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
+
/**
* Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
*/
@@ -34,6 +37,9 @@
/** Name of the auto-registered Ignite proxy factory bean. */
private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
+ /** Name of the auto-registered Ignite proxy bean prototype. */
+ private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
+
/** {@inheritDoc} */
@Override public String getModuleName() {
return "Apache Ignite";
@@ -45,21 +51,30 @@
}
/** {@inheritDoc} */
- @Override public String getRepositoryFactoryClassName() {
+ @Override public String getRepositoryFactoryBeanClassName() {
return IgniteRepositoryFactoryBean.class.getName();
}
/** {@inheritDoc} */
@Override protected Collection<Class<?>> getIdentifyingTypes() {
- return Collections.<Class<?>>singleton(IgniteRepository.class);
+ return Collections.singleton(IgniteRepository.class);
}
/** {@inheritDoc} */
@Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
registerIfNotAlreadyRegistered(
- BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
+ () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
registry,
IGNITE_PROXY_FACTORY_BEAN_NAME,
cfg);
+
+ registerIfNotAlreadyRegistered(
+ () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
+ .setScope(SCOPE_PROTOTYPE)
+ .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
+ .getBeanDefinition(),
+ registry,
+ IGNITE_PROXY_BEAN_NAME,
+ cfg);
}
}
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
index 1095942..0e6bf20 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.ignite.springdata.repository.config;
import java.lang.annotation.Documented;
@@ -22,16 +21,121 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.client.IgniteClient;
/**
- * Annotation to provide a user defined SQL query for a method.
+ * Annotation to provide a user defined query for a method.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Query {
/**
- * SQL query text string.
+ * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
+ * (only if textQuery = false (default))
*/
String value() default "";
+
+ /**
+ * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
+ * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
+ *
+ * @see RepositoryConfig#igniteInstance()
+ */
+ boolean textQuery() default false;
+
+ /**
+ * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
+ * statements or to not return hidden fields on SELECT * statements.
+ */
+ boolean forceFieldsQuery() default false;
+
+ /**
+ * Sets flag defining if this query is collocated.
+ * <p>
+ * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
+ * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
+ * of your query selection are collocated together on the same node and you group by collocated key (primary or
+ * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
+ * nodes.
+ *
+ * <p>
+ * Only applicable to SqlFieldsQuery
+ */
+ boolean collocated() default false;
+
+ /**
+ * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
+ * timeout is exceeded. Zero value disables timeout
+ *
+ * <p>
+ * Only applicable to SqlFieldsQuery and SqlQuery
+ */
+ int timeout() default 0;
+
+ /**
+ * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
+ * tables in join. By default is {@code false}.
+ * <p>
+ * It is not recommended to enable this property until you are sure that your indexes and the query itself are
+ * correct and tuned as much as possible but query optimizer still produces wrong join order.
+ *
+ * <p>
+ * Only applicable to SqlFieldsQuery
+ */
+ boolean enforceJoinOrder() default false;
+
+ /**
+ * Specify if distributed joins are enabled for this query.
+ * <p>
+ * Only applicable to SqlFieldsQuery and SqlQuery
+ */
+ boolean distributedJoins() default false;
+
+ /**
+ * Sets lazy query execution flag.
+ * <p>
+ * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
+ * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
+ * increasing concurrency.
+ * <p>
+ * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
+ * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
+ * consumption at the cost of moderate performance hit.
+ * <p>
+ * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
+ * <p>
+ * Only applicable to SqlFieldsQuery
+ */
+ boolean lazy() default false;
+
+ /**
+ * Sets whether this query should be executed on local node only.
+ */
+ boolean local() default false;
+
+ /**
+ * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
+ * partitions.
+ * <p>
+ * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
+ * <p>
+ * Only applicable to SqlFieldsQuery and SqlQuery
+ */
+ int[] parts() default {};
+
+ /**
+ * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
+ * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
+ * <p>
+ * Please, note that {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
+ * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
+ */
+ boolean dynamicQuery() default false;
+
+ /**
+ * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
+ */
+ int limit() default 0;
}
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
index 4a3703e..e990cba 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
@@ -24,8 +24,16 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+
/**
* The annotation can be used to pass Ignite specific parameters to a bound repository.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@@ -33,7 +41,37 @@
@Inherited
public @interface RepositoryConfig {
/**
+ * Cache name string.
+ *
* @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
*/
String cacheName() default "";
+
+ /**
+ * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
+ * Ignite cluster.
+ */
+ String igniteInstance() default "igniteInstance";
+
+ /**
+ * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
+ * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
+ */
+ String igniteCfg() default "igniteCfg";
+
+ /**
+ * Ignite spring cfg path string. Default "igniteSpringCfgPath".
+ *
+ * @return A path to Ignite's Spring XML configuration spring bean name
+ */
+ String igniteSpringCfgPath() default "igniteSpringCfgPath";
+
+ /**
+ * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
+ * <p>
+ * Tells to Ignite Repository factory wether cache should be auto created if not exists.
+ *
+ * @return the boolean
+ */
+ boolean autoCreateCache() default false;
}
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
index c7f473b..ab142ae 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
@@ -19,5 +19,4 @@
* <!-- Package description. -->
* Package includes Spring Data integration related configuration files.
*/
-
package org.apache.ignite.springdata.repository.config;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
index 773abea..d3dceb6 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
@@ -19,5 +19,4 @@
* <!-- Package description. -->
* Package contains Apache Ignite Spring Data integration.
*/
-
package org.apache.ignite.springdata.repository;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
similarity index 97%
rename from modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
index fa5043d..55e8428 100644
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata20.repository.query;
+package org.apache.ignite.springdata.repository.query;
import java.util.List;
import org.jetbrains.annotations.Nullable;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
similarity index 97%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
index 6f697a2..3359a24 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
import java.util.Collections;
import java.util.List;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
similarity index 98%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
index 9279da7..e296f84 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
import java.util.regex.Pattern;
import org.springframework.data.repository.core.EntityMetadata;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
index f630ca0..37bd3ce 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
@@ -17,8 +17,13 @@
package org.apache.ignite.springdata.repository.query;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
/**
* Ignite query helper class. For internal use only.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
public class IgniteQuery {
/** */
@@ -33,23 +38,47 @@
NONE
}
- /** Sql query text string. */
- private final String sql;
+ /**
+ * Query text string.
+ */
+ private final String qrySql;
- /** */
+ /**
+ * Whether this is a SQL fields query
+ */
private final boolean isFieldQuery;
- /** Type of option. */
+ /**
+ * Whether this is Text query
+ */
+ private final boolean isTextQuery;
+
+ /**
+ * Whether was autogenerated (by method name)
+ */
+ private final boolean isAutogenerated;
+
+ /**
+ * Type of option.
+ */
private final Option option;
/**
- * @param sql Sql.
- * @param isFieldQuery Is field query.
- * @param option Option.
+ * @param qrySql the query string.
+ * @param isFieldQuery Is field query.
+ * @param isTextQuery Is a TextQuery
+ * @param isAutogenerated query was autogenerated
+ * @param option Option.
*/
- public IgniteQuery(String sql, boolean isFieldQuery, Option option) {
- this.sql = sql;
+ public IgniteQuery(String qrySql,
+ boolean isFieldQuery,
+ boolean isTextQuery,
+ boolean isAutogenerated,
+ Option option) {
+ this.qrySql = qrySql;
this.isFieldQuery = isFieldQuery;
+ this.isTextQuery = isTextQuery;
+ this.isAutogenerated = isAutogenerated;
this.option = option;
}
@@ -58,8 +87,8 @@
*
* @return SQL query text string.
*/
- public String sql() {
- return sql;
+ public String qryStr() {
+ return qrySql;
}
/**
@@ -72,6 +101,24 @@
}
/**
+ * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
+ *
+ * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
+ */
+ public boolean isTextQuery() {
+ return isTextQuery;
+ }
+
+ /**
+ * Returns {@code true} if it's autogenerated, {@code false} otherwise.
+ *
+ * @return {@code true} if it's autogenerated, {@code false} otherwise.
+ */
+ public boolean isAutogenerated() {
+ return isAutogenerated;
+ }
+
+ /**
* Advanced querying option.
*
* @return querying option.
@@ -79,5 +126,9 @@
public Option options() {
return option;
}
-}
+ /** */
+ @Override public String toString() {
+ return S.toString(IgniteQuery.class, this);
+ }
+}
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
index e1f3f2f..6bf02bc 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
@@ -18,7 +18,6 @@
package org.apache.ignite.springdata.repository.query;
import java.lang.reflect.Method;
-import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.PropertyPath;
@@ -31,12 +30,17 @@
* Ignite query generator for Spring Data framework.
*/
public class IgniteQueryGenerator {
+ /** */
+ private IgniteQueryGenerator() {
+ // No-op.
+ }
/**
- * @param mtd Method.
+ * @param mtd Method.
* @param metadata Metadata.
+ * @return Generated ignite query.
*/
- @NotNull public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
+ public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
PartTree parts;
try {
@@ -46,20 +50,26 @@
parts = new PartTree(mtd.getName(), metadata.getIdType());
}
+ boolean isCountOrFieldQuery = parts.isCountProjection();
+
StringBuilder sql = new StringBuilder();
- if (parts.isDelete())
- throw new UnsupportedOperationException("DELETE clause is not supported now.");
+ if (parts.isDelete()) {
+ sql.append("DELETE ");
+
+ // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
+ isCountOrFieldQuery = true;
+ }
else {
sql.append("SELECT ");
if (parts.isDistinct())
throw new UnsupportedOperationException("DISTINCT clause in not supported.");
- if (parts.isCountProjection())
+ if (isCountOrFieldQuery)
sql.append("COUNT(1) ");
else
- sql.append(" * ");
+ sql.append("* ");
}
sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
@@ -69,6 +79,7 @@
for (PartTree.OrPart orPart : parts) {
sql.append("(");
+
for (Part part : orPart) {
handleQueryPart(sql, part, metadata.getDomainType());
sql.append(" AND ");
@@ -89,17 +100,18 @@
sql.append(parts.getMaxResults().intValue());
}
- return new IgniteQuery(sql.toString(), parts.isCountProjection(), getOptions(mtd));
+ return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
}
/**
* Add a dynamic part of query for the sorting support.
*
- * @param sql SQL text string.
+ * @param sql SQL text string.
* @param sort Sort method.
+ * @return Sorting criteria in StringBuilder.
*/
public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
- if (sort != null) {
+ if (sort != null && sort != Sort.unsorted()) {
sql.append(" ORDER BY ");
for (Sort.Order order : sort) {
@@ -107,6 +119,7 @@
if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
sql.append(" ").append("NULL ");
+
switch (order.getNullHandling()) {
case NULLS_FIRST:
sql.append("FIRST");
@@ -114,6 +127,7 @@
case NULLS_LAST:
sql.append("LAST");
break;
+ default:
}
}
sql.append(", ");
@@ -128,13 +142,13 @@
/**
* Add a dynamic part of a query for the pagination support.
*
- * @param sql Builder instance.
+ * @param sql Builder instance.
* @param pageable Pageable instance.
* @return Builder instance.
*/
public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
- if (pageable.getSort() != null)
- addSorting(sql, pageable.getSort());
+
+ addSorting(sql, pageable.getSort());
sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
@@ -151,7 +165,6 @@
IgniteQuery.Option option = IgniteQuery.Option.NONE;
Class<?>[] types = mtd.getParameterTypes();
-
if (types.length > 0) {
Class<?> type = types[types.length - 1];
@@ -163,6 +176,7 @@
for (int i = 0; i < types.length - 1; i++) {
Class<?> tp = types[i];
+
if (tp == Sort.class || tp == Pageable.class)
throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
}
@@ -183,7 +197,7 @@
}
/**
- * Transform part to sql expression
+ * Transform part to qryStr expression
*/
private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
sql.append("(");
@@ -224,15 +238,13 @@
case TRUE:
sql.append(" = TRUE");
break;
+ //TODO: review this legacy code, LIKE should be -> LIKE ?
+ case LIKE:
case CONTAINING:
sql.append(" LIKE '%' || ? || '%'");
break;
case NOT_CONTAINING:
- sql.append(" NOT LIKE '%' || ? || '%'");
- break;
- case LIKE:
- sql.append(" LIKE '%' || ? || '%'");
- break;
+ //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
case NOT_LIKE:
sql.append(" NOT LIKE '%' || ? || '%'");
break;
@@ -262,4 +274,3 @@
sql.append(")");
}
}
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
index 79ce6c0..6736388 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
@@ -17,39 +17,151 @@
package org.apache.ignite.springdata.repository.query;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.cache.Cache;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.reflect.FieldUtils;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.Query;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cache.query.TextQuery;
import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.springdata.repository.config.DynamicQueryConfig;
+import org.apache.ignite.springdata.repository.query.StringQuery.ParameterBinding;
import org.jetbrains.annotations.Nullable;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.Parameter;
+import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.QueryMethod;
+import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ParserContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.util.StringUtils;
-import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addPaging;
-import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addSorting;
+import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
+import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
+import static org.apache.ignite.springdata.repository.support.IgniteRepositoryFactory.isFieldQuery;
/**
- * Ignite SQL query implementation.
+ * Ignite query implementation.
+ * <p>
+ * <p>
+ * Features:
+ * <ol>
+ * <li> Supports query tuning parameters</li>
+ * <li> Supports projections</li>
+ * <li> Supports Page and Stream responses</li>
+ * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
+ * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
+ * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
+ * <ol>
+ * <li><b>Template variables</b>:
+ * <ol>
+ * <li>{@code #entityName} - the simple class name of the domain entity</li>
+ * </ol>
+ * </li>
+ * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
+ * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
+ * ?#{[0]} or ?#{#myParamName}</li>
+ * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
+ * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
+ * through SpEL EvaluationContext extension model.</li>
+ * </ol>
+ * Examples:
+ * <pre>
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
+ * User searchUserByEmail({@code @Param}("email") String email);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
+ * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
+ * Pageable pageable);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
+ * User searchUserByEmail(String email);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
+ * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
+ * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
+ * </pre>
+ * </li>
+ * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
+ * <pre>
+ * {@code @Query}(textQuery = true, value = "email: #{#email}")
+ * User searchUserByEmail({@code @Param}("email") String email);
+ *
+ * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
+ * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
+ *
+ * {@code @Query}(textQuery = true, value = "#{[0]}")
+ * List<User> searchUsersByText(String textToSearch, Pageable pageable);
+ *
+ * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
+ * .match('city', #city)).build()}")
+ * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
+ * </pre>
+ * </li>
+ * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
+ * <pre>
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
+ * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
+ *
+ * {@code @Query}(dynamicQuery = true)
+ * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
+ * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
+ *
+ * ...
+ * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
+ * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
+ *
+ * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
+ * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
+ *
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
-@SuppressWarnings({"unchecked", "rawtypes"})
+@SuppressWarnings("unchecked")
public class IgniteRepositoryQuery implements RepositoryQuery {
- /** Defines the way how to process query result */
+ /**
+ * Defines the way how to process query result
+ */
private enum ReturnStrategy {
/** Need to return only one value. */
ONE_VALUE,
@@ -69,60 +181,181 @@
/** Need to return slice */
SLICE_OF_VALUES,
- /** Slice of cache entries. */
+ /** Slice of cache entries */
SLICE_OF_CACHE_ENTRIES,
- /** Slice of lists. */
- SLICE_OF_LISTS
+ /** Slice of lists */
+ SLICE_OF_LISTS,
+
+ /** Need to return Page of values */
+ PAGE_OF_VALUES,
+
+ /** Need to return stream of values */
+ STREAM_OF_VALUES,
}
- /** Type. */
+ /** */
private final Class<?> type;
- /** Sql. */
- private final IgniteQuery qry;
+ /** Domain entitiy field descriptors mapped to their names in lower case. */
+ private final Map<String, Field> domainEntitiyFields;
- /** Cache. */
+ /** */
+ private final IgniteQuery staticQuery;
+
+ /** */
private final IgniteCacheProxy<?, ?> cache;
- /** Method. */
+ /** */
private final Method mtd;
- /** Metadata. */
+ /** */
private final RepositoryMetadata metadata;
- /** Factory. */
+ /** */
private final ProjectionFactory factory;
- /** Return strategy. */
- private final ReturnStrategy returnStgy;
+ /** */
+ private final ReturnStrategy staticReturnStgy;
+
+ /** Detect if returned data from method is projected */
+ private final boolean hasProjection;
+
+ /** Whether projection is dynamic (provided as method parameter) */
+ private final boolean hasDynamicProjection;
+
+ /** Dynamic projection parameter index */
+ private final int dynamicProjectionIndex;
+
+ /** Dynamic query configuration */
+ private final int dynamicQueryConfigurationIndex;
+
+ /** The return query method */
+ private final QueryMethod qMethod;
+
+ /** The return domain class of QueryMethod */
+ private final Class<?> returnedDomainClass;
+
+ /** */
+ private final SpelExpressionParser expressionParser;
+
+ /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
+ private final QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider;
+
+ /** Static query configuration. */
+ private final DynamicQueryConfig staticQueryConfiguration;
/**
- * @param metadata Metadata.
- * @param qry Query.
- * @param mtd Method.
- * @param factory Factory.
- * @param cache Cache.
+ * Instantiates a new Ignite repository query.
+ *
+ * @param metadata Metadata.
+ * @param staticQuery Query.
+ * @param mtd Method.
+ * @param factory Factory.
+ * @param cache Cache.
+ * @param staticQueryConfiguration the query configuration
+ * @param queryMethodEvaluationContextProvider the query method evaluation context provider
*/
- public IgniteRepositoryQuery(RepositoryMetadata metadata, IgniteQuery qry,
- Method mtd, ProjectionFactory factory, IgniteCacheProxy<?, ?> cache) {
- type = metadata.getDomainType();
- this.qry = qry;
- this.cache = cache;
+ public IgniteRepositoryQuery(
+ RepositoryMetadata metadata,
+ @Nullable IgniteQuery staticQuery,
+ Method mtd,
+ ProjectionFactory factory,
+ IgniteCacheProxy<? ,?> cache,
+ @Nullable DynamicQueryConfig staticQueryConfiguration,
+ QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider) {
this.metadata = metadata;
this.mtd = mtd;
this.factory = factory;
+ type = metadata.getDomainType();
- returnStgy = calcReturnType(mtd, qry.isFieldQuery());
+ domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
+ .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
+
+ this.cache = cache;
+
+ this.staticQueryConfiguration = staticQueryConfiguration;
+ this.staticQuery = staticQuery;
+
+ if (this.staticQuery != null)
+ staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
+ else
+ staticReturnStgy = null;
+
+ expressionParser = new SpelExpressionParser();
+ this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
+
+ qMethod = getQueryMethod();
+
+ // control projection
+ hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
+ hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
+ .isProjecting();
+
+ dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
+
+ returnedDomainClass = getQueryMethod().getReturnedObjectType();
+
+ dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
+
+ // ensure dynamic query configuration param exists if dynamicQuery = true
+ if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
+ throw new IllegalStateException(
+ "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
+ + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
+ }
}
- /** {@inheritDoc} */
- @Override public Object execute(Object[] prmtrs) {
- Query qry = prepareQuery(prmtrs);
+ /**
+ * {@inheritDoc} @param values the values
+ *
+ * @return the object
+ */
+ @Override public Object execute(Object[] values) {
+ Object[] parameters = values;
- try (QueryCursor qryCursor = cache.query(qry)) {
- return transformQueryCursor(prmtrs, qryCursor);
+ // config via Query annotation (dynamicQuery = false)
+ DynamicQueryConfig config = staticQueryConfiguration;
+
+ // or condition to allow query tunning
+ if (config == null || dynamicQueryConfigurationIndex != -1) {
+ DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
+ parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
+ if (newConfig != null) {
+ // upset query configuration
+ config = newConfig;
+ }
}
+ // query configuration is required, via Query annotation or per parameter (within provided values param)
+ if (config == null) {
+ throw new IllegalStateException(
+ "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
+ + ".repository.config.Query annotation, you must provide a non null method parameter of type "
+ + "DynamicQueryConfig");
+ }
+
+ IgniteQuery qry = getQuery(config);
+
+ ReturnStrategy returnStgy = getReturnStgy(qry);
+
+ Query iQry = prepareQuery(qry, config, returnStgy, parameters);
+
+ QueryCursor qryCursor;
+
+ try {
+ qryCursor = cache.query(iQry);
+ }
+ catch (IllegalArgumentException e) {
+ if (cache instanceof IgniteClientCacheProxy) {
+ throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
+ " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
+ iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
+ }
+
+ throw e;
+ }
+
+ return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
}
/** {@inheritDoc} */
@@ -130,6 +363,29 @@
return new QueryMethod(mtd, metadata, factory);
}
+ private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
+ Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
+ int i = 0;
+ boolean found = false;
+ int index = -1;
+ while (it.hasNext()) {
+ T parameter = it.next();
+
+ if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
+ if (found) {
+ throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
+ + "Only ONE DynamicQueryConfig parameter is allowed");
+ }
+
+ found = true;
+ index = i;
+ }
+
+ i++;
+ }
+ return index;
+ }
+
/**
* @param mtd Method.
* @param isFieldQry Is field query.
@@ -138,39 +394,46 @@
private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
Class<?> returnType = mtd.getReturnType();
- if (returnType.isAssignableFrom(ArrayList.class)) {
- if (isFieldQry) {
- if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
- return ReturnStrategy.LIST_OF_LISTS;
- }
- else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
- return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
-
- return ReturnStrategy.LIST_OF_VALUES;
- }
- else if (returnType == Slice.class) {
+ if (returnType == Slice.class) {
if (isFieldQry) {
if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
return ReturnStrategy.SLICE_OF_LISTS;
}
else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
-
return ReturnStrategy.SLICE_OF_VALUES;
}
+ else if (returnType == Page.class)
+ return ReturnStrategy.PAGE_OF_VALUES;
+ else if (returnType == Stream.class)
+ return ReturnStrategy.STREAM_OF_VALUES;
else if (Cache.Entry.class.isAssignableFrom(returnType))
return ReturnStrategy.CACHE_ENTRY;
+ else if (Iterable.class.isAssignableFrom(returnType)) {
+ if (isFieldQry) {
+ if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+ return ReturnStrategy.LIST_OF_LISTS;
+ }
+ else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
+ return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
+ return ReturnStrategy.LIST_OF_VALUES;
+ }
else
return ReturnStrategy.ONE_VALUE;
}
/**
- * @param cls Class 1.
+ * @param cls Class.
* @param mtd Method.
* @return if {@code mtd} return type is assignable from {@code cls}
*/
private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
- Type[] actualTypeArguments = ((ParameterizedType)mtd.getGenericReturnType()).getActualTypeArguments();
+ Type genericReturnType = mtd.getGenericReturnType();
+
+ if (!(genericReturnType instanceof ParameterizedType))
+ return false;
+
+ Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
if (actualTypeArguments.length == 0)
return false;
@@ -193,91 +456,185 @@
}
/**
- * @param prmtrs Prmtrs.
+ * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
+ *
+ * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
+ * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
+ */
+ private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
+ if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
+ return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
+
+ return (T)object;
+ }
+
+ /**
+ * @param cfg Config.
+ */
+ private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
+ if (staticQuery != null)
+ return staticQuery;
+
+ if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
+ return new IgniteQuery(cfg.value(),
+ !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
+ false, IgniteQueryGenerator.getOptions(mtd));
+ }
+
+ throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
+ + ".apache.ignite.springdata.repository.config.Query annotation, you must"
+ + " provide a non null method parameter of type DynamicQueryConfig with a "
+ + "non empty value (query string) or textQuery = true");
+ }
+
+ /**
+ * @param qry Query.
+ */
+ private ReturnStrategy getReturnStgy(IgniteQuery qry) {
+ if (staticReturnStgy != null)
+ return staticReturnStgy;
+
+ if (qry != null)
+ return calcReturnType(mtd, qry.isFieldQuery());
+
+ throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
+ + "via org.apache.ignite.springdata.repository.config.Query annotation, "
+ + "you must provide a non null method parameter of type "
+ + "DynamicQueryConfig with a non empty value (query string) or textQuery "
+ + "= true");
+ }
+
+ /**
+ * @param cls Class.
+ */
+ private static boolean isPrimitiveOrWrapper(Class<?> cls) {
+ return cls.isPrimitive() ||
+ Boolean.class.equals(cls) ||
+ Byte.class.equals(cls) ||
+ Character.class.equals(cls) ||
+ Short.class.equals(cls) ||
+ Integer.class.equals(cls) ||
+ Long.class.equals(cls) ||
+ Float.class.equals(cls) ||
+ Double.class.equals(cls) ||
+ Void.class.equals(cls) ||
+ String.class.equals(cls) ||
+ UUID.class.equals(cls);
+ }
+
+ /**
+ * @param prmtrs Prmtrs.
* @param qryCursor Query cursor.
* @return Query cursor or slice
*/
- @Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
+ @Nullable
+ private Object transformQueryCursor(IgniteQuery qry,
+ ReturnStrategy returnStgy,
+ Object[] prmtrs,
+ QueryCursor qryCursor) {
+ final Class<?> returnClass;
+
+ if (hasProjection) {
+ if (hasDynamicProjection)
+ returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
+ else
+ returnClass = returnedDomainClass;
+ }
+ else
+ returnClass = returnedDomainClass;
+
if (qry.isFieldQuery()) {
- Iterable<List> qryIter = (Iterable<List>)qryCursor;
+ // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
+ boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
+
+ FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
+
+ Function<List<?>, ?> cWrapperTransformFunction = null;
+
+ if (type.equals(returnClass))
+ cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
+ else {
+ if (hasProjection || singlePrimitiveResult) {
+ if (singlePrimitiveResult)
+ cWrapperTransformFunction = row -> row.get(0);
+ else {
+ // Map row -> projection class
+ cWrapperTransformFunction = row -> factory
+ .createProjection(returnClass, rowToMap(row, fieldQryCur));
+ }
+ }
+ else
+ cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
+ }
+
+ QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
+ cWrapperTransformFunction);
switch (returnStgy) {
+ case PAGE_OF_VALUES:
+ return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
case LIST_OF_VALUES:
- List list = new ArrayList<>();
-
- for (List entry : qryIter)
- list.add(entry.get(0));
-
- return list;
-
+ return cWrapper.getAll();
+ case STREAM_OF_VALUES:
+ return cWrapper.stream();
case ONE_VALUE:
- Iterator<List> iter = qryIter.iterator();
-
- if (iter.hasNext())
- return iter.next().get(0);
-
+ Iterator<?> iter = cWrapper.iterator();
+ if (iter.hasNext()) {
+ Object resp = iter.next();
+ U.closeQuiet(cWrapper);
+ return resp;
+ }
return null;
-
case SLICE_OF_VALUES:
- List content = new ArrayList<>();
-
- for (List entry : qryIter)
- content.add(entry.get(0));
-
- return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
-
+ return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
case SLICE_OF_LISTS:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-
case LIST_OF_LISTS:
return qryCursor.getAll();
-
default:
throw new IllegalStateException();
}
}
else {
- Iterable<Cache.Entry<?, ?>> qryIter = (Iterable<Cache.Entry<?, ?>>)qryCursor;
+ Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
+
+ if (hasProjection && !type.equals(returnClass))
+ cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
+ else
+ cWrapperTransformFunction = Cache.Entry::getValue;
+
+ QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
+ (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
switch (returnStgy) {
+ case PAGE_OF_VALUES:
+ return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
case LIST_OF_VALUES:
- List list = new ArrayList<>();
-
- for (Cache.Entry<?, ?> entry : qryIter)
- list.add(entry.getValue());
-
- return list;
-
+ return cWrapper.getAll();
+ case STREAM_OF_VALUES:
+ return cWrapper.stream();
case ONE_VALUE:
- Iterator<Cache.Entry<?, ?>> iter1 = qryIter.iterator();
-
- if (iter1.hasNext())
- return iter1.next().getValue();
-
+ Iterator<?> iter1 = cWrapper.iterator();
+ if (iter1.hasNext()) {
+ Object resp = iter1.next();
+ U.closeQuiet(cWrapper);
+ return resp;
+ }
return null;
-
case CACHE_ENTRY:
- Iterator<Cache.Entry<?, ?>> iter2 = qryIter.iterator();
-
- if (iter2.hasNext())
- return iter2.next();
-
+ Iterator<?> iter2 = qryCursor.iterator();
+ if (iter2.hasNext()) {
+ Object resp2 = iter2.next();
+ U.closeQuiet(qryCursor);
+ return resp2;
+ }
return null;
-
case SLICE_OF_VALUES:
- List content = new ArrayList<>();
-
- for (Cache.Entry<?, ?> entry : qryIter)
- content.add(entry.getValue());
-
- return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
-
+ return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
case SLICE_OF_CACHE_ENTRIES:
return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-
case LIST_OF_CACHE_ENTRIES:
return qryCursor.getAll();
-
default:
throw new IllegalStateException();
}
@@ -285,41 +642,329 @@
}
/**
- * @param prmtrs Prmtrs.
+ * Extract bindable values
+ *
+ * @param values values invoking query method
+ * @param queryMethodParams query method parameter definitions
+ * @param queryBindings All parameters found on query string that need to be binded
+ * @return new list of parameters
+ */
+ private Object[] extractBindableValues(Object[] values,
+ Parameters<?, ?> queryMethodParams,
+ List<ParameterBinding> queryBindings) {
+ // no binding params then exit
+ if (queryBindings.isEmpty())
+ return values;
+
+ Object[] newValues = new Object[queryBindings.size()];
+
+ // map bindable parameters from query method: (index/name) - index
+ HashMap<String, Integer> methodParams = new HashMap<>();
+
+ // create an evaluation context for custom query
+ EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
+ .getEvaluationContext(queryMethodParams, values);
+
+ // By default queryEvalContext:
+ // - make accesible query method parameters by index:
+ // @Query("select u from User u where u.age = ?#{[0]}")
+ // List<User> findUsersByAge(int age);
+ // - make accesible query method parameters by name:
+ // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
+ // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
+
+ // query method param's index by name and position
+ queryMethodParams.getBindableParameters().forEach(p -> {
+ if (p.isNamedParameter()) {
+ // map by name (annotated by @Param)
+ methodParams.put(p.getName().get(), p.getIndex());
+ }
+ // map by position
+ methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
+ });
+
+ // process all parameters on query and extract new values to bind
+ for (int i = 0; i < queryBindings.size(); i++) {
+ ParameterBinding p = queryBindings.get(i);
+
+ if (p.isExpression()) {
+ // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
+ newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
+ }
+ else {
+ // Extract parameter value by name or position respectively from invoking values
+ newValues[i] = values[methodParams.get(
+ p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
+ }
+ }
+
+ return newValues;
+ }
+
+ /**
+ * @param qry Query.
+ * @param config Config.
+ * @param returnStgy Return stgy.
+ * @param values Values.
* @return prepared query for execution
*/
- @SuppressWarnings("deprecation")
- @NotNull private Query prepareQuery(Object[] prmtrs) {
- Object[] parameters = prmtrs;
- String sql = qry.sql();
+ private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
+ Object[] parameters = values;
- switch (qry.options()) {
- case SORTING:
- sql = addSorting(new StringBuilder(sql), (Sort)parameters[parameters.length - 1]).toString();
- parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+ String queryString = qry.qryStr();
- break;
+ Query query;
- case PAGINATION:
- sql = addPaging(new StringBuilder(sql), (Pageable)parameters[parameters.length - 1]).toString();
- parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+ checkRequiredPageable(returnStgy, values);
- break;
+ if (!qry.isTextQuery()) {
+ if (!qry.isAutogenerated()) {
+ StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
+ queryString = squery.getQueryString();
+ parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
+ squery.getParameterBindings());
+ }
+ else {
+ // remove dynamic projection from parameters
+ if (hasDynamicProjection)
+ parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
+ }
- case NONE:
- // No-op.
+ switch (qry.options()) {
+ case SORTING:
+ queryString = IgniteQueryGenerator
+ .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
+ .toString();
+ if (qry.isAutogenerated())
+ parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
+ break;
+ case PAGINATION:
+ queryString = IgniteQueryGenerator
+ .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
+ .toString();
+ if (qry.isAutogenerated())
+ parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
+ break;
+ default:
+ }
+
+ if (qry.isFieldQuery()) {
+ SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
+ sqlFieldsQry.setArgs(parameters);
+
+ sqlFieldsQry.setCollocated(config.collocated());
+ sqlFieldsQry.setDistributedJoins(config.distributedJoins());
+ sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
+ sqlFieldsQry.setLazy(config.lazy());
+ sqlFieldsQry.setLocal(config.local());
+
+ if (config.parts() != null && config.parts().length > 0)
+ sqlFieldsQry.setPartitions(config.parts());
+
+ sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
+
+ query = sqlFieldsQry;
+ }
+ else {
+ SqlQuery sqlQry = new SqlQuery(type, queryString);
+ sqlQry.setArgs(parameters);
+
+ sqlQry.setDistributedJoins(config.distributedJoins());
+ sqlQry.setLocal(config.local());
+
+ if (config.parts() != null && config.parts().length > 0)
+ sqlQry.setPartitions(config.parts());
+
+ sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
+
+ query = sqlQry;
+ }
+ }
+ else {
+ int pageSize = -1;
+
+ switch (qry.options()) {
+ case PAGINATION:
+ pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
+ break;
+ }
+
+ // check if queryString contains SpEL template expressions and evaluate them if any
+ if (queryString.contains("#{")) {
+ EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
+ .getEvaluationContext(getQueryMethod().getParameters(),
+ values);
+
+ Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
+ .getValue(queryEvalContext);
+
+ if (!(eval instanceof String)) {
+ throw new IllegalStateException(
+ "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
+ .getName()
+ + ". Please, check your expression: " + queryString);
+ }
+ queryString = (String)eval;
+ }
+
+ TextQuery textQuery = new TextQuery(type, queryString, config.limit());
+
+ textQuery.setLocal(config.local());
+
+ if (pageSize > -1)
+ textQuery.setPageSize(pageSize);
+
+ query = textQuery;
+ }
+ return query;
+ }
+
+ /**
+ * @param row SQL result row.
+ * @param cursor SQL query result cursor through which {@param row} was obtained.
+ * @return SQL result row values mapped to corresponding column names.
+ */
+ private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
+ // use treemap with case insensitive property name
+ final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ for (int i = 0; i < row.size(); i++) {
+ // don't want key or val columns
+ final String fieldName = cursor.getFieldName(i).toLowerCase();
+
+ if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
+ map.put(fieldName, row.get(i));
}
- if (qry.isFieldQuery()) {
- SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
- sqlFieldsQry.setArgs(parameters);
+ return map;
+ }
- return sqlFieldsQry;
+ /**
+ * convert row ( with list of field values) into domain entity
+ *
+ * @param row SQL query result row.
+ * @param cursor SQL query result cursor through which {@param row} was obtained.
+ * @return Entitiy instance.
+ */
+ private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
+ Constructor<?> ctor;
+
+ try {
+ ctor = type.getDeclaredConstructor();
+
+ ctor.setAccessible(true);
+ }
+ catch (NoSuchMethodException | SecurityException ignored) {
+ ctor = null;
}
- SqlQuery sqlQry = new SqlQuery(type, sql);
- sqlQry.setArgs(parameters);
+ try {
+ Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
- return sqlQry;
+ for (int i = 0; i < row.size(); i++) {
+ Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
+
+ if (entityField != null)
+ FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
+ }
+
+ return (V)res;
+ }
+ catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
+ }
+ }
+
+ /**
+ * Validates operations that requires Pageable parameter
+ *
+ * @param returnStgy Return stgy.
+ * @param prmtrs Prmtrs.
+ */
+ private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
+ try {
+ if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
+ || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
+ Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
+ page.isPaged();
+ }
+ }
+ catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
+ throw new IllegalStateException(
+ "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
+ }
+ }
+
+ /**
+ * Ignite QueryCursor wrapper.
+ * <p>
+ * Ensures closing underline cursor when there is no data.
+ *
+ * @param <T> input type
+ * @param <V> transformed output type
+ */
+ public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
+ /**
+ * Delegate query cursor.
+ */
+ private final QueryCursor<T> delegate;
+
+ /**
+ * Transformer.
+ */
+ private final Function<T, V> transformer;
+
+ /**
+ * Instantiates a new Query cursor wrapper.
+ *
+ * @param delegate delegate QueryCursor with T input elements
+ * @param transformer Function to transform T to V elements
+ */
+ public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
+ this.delegate = delegate;
+ this.transformer = transformer;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterator<V> iterator() {
+ final Iterator<T> it = delegate.iterator();
+
+ return new Iterator<V>() {
+ /** */
+ @Override public boolean hasNext() {
+ if (!it.hasNext()) {
+ U.closeQuiet(delegate);
+ return false;
+ }
+ return true;
+ }
+
+ /** */
+ @Override public V next() {
+ final V r = transformer.apply(it.next());
+ if (r != null)
+ return r;
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public void close() {
+ U.closeQuiet(delegate);
+ }
+
+ /** {@inheritDoc} */
+ @Override public List<V> getAll() {
+ final List<V> data = new ArrayList<>();
+ delegate.forEach(i -> data.add(transformer.apply(i)));
+ U.closeQuiet(delegate);
+ return data;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int size() {
+ return 0;
+ }
}
}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
similarity index 99%
rename from modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
index a44ae6c..ba8c4aa 100644
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata20.repository.query;
+package org.apache.ignite.springdata.repository.query;
import java.util.HashSet;
import java.util.Set;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
similarity index 99%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
index 01af166..e54552b 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
import java.lang.reflect.Array;
import java.util.ArrayList;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
index 9b6fdb1..6046af4 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
@@ -19,5 +19,4 @@
* <!-- Package description. -->
* Package includes classes that integrates with Apache Ignite SQL engine.
*/
-
package org.apache.ignite.springdata.repository.query;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
similarity index 95%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
index a69dc8e..a407d43 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.springdata22.repository.support;
+package org.apache.ignite.springdata.repository.support;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
index ba19f93..1f8bf81 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
@@ -17,59 +17,100 @@
package org.apache.ignite.springdata.repository.support;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import org.apache.ignite.Ignite;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.springdata.proxy.IgniteProxy;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.config.BeanExpressionResolver;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.expression.StandardBeanExpressionResolver;
/**
- * Represents factory for obtaining instance of {@link IgniteProxy} that provide client-independent connection to the
+ * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
* Ignite cluster.
*/
-public class IgniteProxyFactory extends AbstractFactoryBean<IgniteProxy> implements ApplicationContextAware {
- /** Name of the bean that stores Ignite client instance to access the Ignite cluster. */
- private static final String IGNITE_INSTANCE_BEAN_NAME = "igniteInstance";
+public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
+ /** Spring application expression resolver. */
+ private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
- /** Name of the bean that stores the configuration to instantiate the Ignite client. */
- private static final String IGNITE_CONFIG_BEAN_NAME = "igniteCfg";
-
- /** Name of the bean that stores the Spring configuration path to instantiate the Ignite client. */
- private static final String IGNITE_SPRING_CONFIG_PATH_BEAN_NAME= "igniteSpringCfgPath";
+ /** Repositories associated with Ignite proxy. */
+ private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
/** Spring application context. */
private ApplicationContext ctx;
+ /** Spring application bean expression context. */
+ private BeanExpressionContext beanExpressionCtx;
+
+ /**
+ * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
+ * @return {@link IgniteProxy} instance.
+ */
+ public IgniteProxy igniteProxy(Class<?> repoInterface) {
+ return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
+ }
+
/** {@inheritDoc} */
@Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.ctx = ctx;
+
+ beanExpressionCtx = new BeanExpressionContext(
+ new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
+ null);
}
/** {@inheritDoc} */
@Override public void destroy() throws Exception {
- Object igniteProxy = getObject();
+ Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
- if (igniteProxy instanceof AutoCloseable)
- ((AutoCloseable)igniteProxy).close();
+ Exception destroyE = null;
+
+ for (IgniteProxy proxy : proxies) {
+ if (proxy instanceof AutoCloseable) {
+ try {
+ ((AutoCloseable)proxy).close();
+ }
+ catch (Exception e) {
+ if (destroyE == null)
+ destroyE = e;
+ else
+ destroyE.addSuppressed(e);
+ }
+ }
+ }
+
+ if (destroyE != null)
+ throw destroyE;
}
- /** {@inheritDoc} */
- @Override public Class<?> getObjectType() {
- return IgniteProxy.class;
- }
+ /**
+ * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
+ *
+ * @param repoInterface {@link Class} instance of the repository interface.
+ * @return Instance of {@link IgniteProxy} associated with specified repository.
+ *
+ * @see RepositoryConfig
+ */
+ private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
+ RepositoryConfig repoCfg = IgniteRepositoryFactory.getRepositoryConfiguration(repoInterface);
- /** {@inheritDoc} */
- @Override protected IgniteProxy createInstance() {
return Stream.<BeanFinder>of(
- () -> ctx.getBean(IGNITE_INSTANCE_BEAN_NAME),
- () -> ctx.getBean(IGNITE_CONFIG_BEAN_NAME),
- () -> ctx.getBean(IGNITE_SPRING_CONFIG_PATH_BEAN_NAME, String.class),
+ () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
+ () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
+ () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
() -> ctx.getBean(Ignite.class),
() -> ctx.getBean(IgniteClient.class),
() -> ctx.getBean(IgniteConfiguration.class),
@@ -79,15 +120,25 @@
.findFirst()
.map(IgniteProxy::of)
.orElseThrow(() -> {
- return new IllegalArgumentException("No beans were found that provide connection configuration to" +
- " the Ignite cluster. One of the beans with the following names is required : \"" +
- IGNITE_INSTANCE_BEAN_NAME + "\", \"" + IGNITE_CONFIG_BEAN_NAME + "\" or \"" +
- IGNITE_SPRING_CONFIG_PATH_BEAN_NAME + "\". You can also provide Ignite, IgniteClient," +
- " IgniteConfiguration or ClientConfiguration bean to application context.");
+ return new IllegalArgumentException("Invalid configuration for repository " +
+ repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
+ " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
+ " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
+ " ClientConfiguration or IgniteConfiguration bean to application context.");
});
}
/**
+ * Evaluates the SpEL expression.
+ *
+ * @param spelExpression SpEL expression
+ * @return The result of evaluation of the SpEL expression.
+ */
+ private String evaluateExpression(String spelExpression) {
+ return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
+ }
+
+ /**
* Helper interface that wraps getBean method.
*/
@FunctionalInterface
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
index 8649733..56e3e21 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
@@ -16,63 +16,90 @@
*/
package org.apache.ignite.springdata.repository.support;
-import java.io.Serializable;
-import java.lang.reflect.Method;
+import java.util.Optional;
import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.repository.config.Query;
-import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.apache.ignite.springdata.repository.query.IgniteQuery;
import org.apache.ignite.springdata.repository.query.IgniteQueryGenerator;
import org.apache.ignite.springdata.repository.query.IgniteRepositoryQuery;
-import org.springframework.data.projection.ProjectionFactory;
+import org.apache.ignite.springdata.repository.config.DynamicQueryConfig;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.AbstractEntityInformation;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.EvaluationContextProvider;
import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Crucial for spring-data functionality class. Create proxies for repositories.
+ * <p>
+ * Supports multiple Ignite Instances on same JVM.
+ * <p>
+ * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
public class IgniteRepositoryFactory extends RepositoryFactorySupport {
+ /** Spring application expression resolver */
+ private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
+
+ /** Spring application bean expression context */
+ private final BeanExpressionContext beanExpressionContext;
+
/** Ignite cache proxy instance associated with the current repository. */
private final IgniteCacheProxy<?, ?> cache;
+ /** Ignite proxy instance associated with the current repository. */
+ private final IgniteProxy ignite;
+
/**
- * Creates the factory with initialized {@link IgniteProxy} instance.
- *
- * @param ignite Ignite proxy instance.
+ * @param ctx Spring Application context.
* @param repoInterface Repository interface.
*/
- public IgniteRepositoryFactory(IgniteProxy ignite, Class<?> repoInterface) {
- RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
+ public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
+ ignite = ctx.getBean(IgniteProxy.class, repoInterface);
- Assert.notNull(cfg, "Invalid repository configuration [name=" + repoInterface.getName() + "]. " +
- RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
+ beanExpressionContext = new BeanExpressionContext(
+ new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
+ null);
- String cacheName = cfg.cacheName();
+ RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
- Assert.hasText(cacheName, "Invalid repository configuration [name=" + repoInterface.getName() + "]." +
- " Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
+ String cacheName = evaluateExpression(cfg.cacheName());
+
+ Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
+ ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
" annotation to map this repository to the underlying cache.");
- cache = ignite.getOrCreateCache(cacheName);
+ cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
+
+ if (cache == null) {
+ throw new IllegalArgumentException(
+ "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
+ + ". Please, add a cache configuration to ignite configuration"
+ + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
+ }
}
/** {@inheritDoc} */
- @Override public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
+ @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
return new AbstractEntityInformation<T, ID>(domainClass) {
+ /** {@inheritDoc} */
@Override public ID getId(T entity) {
return null;
}
+ /** {@inheritDoc} */
@Override public Class<ID> getIdType() {
return null;
}
@@ -84,51 +111,96 @@
return IgniteRepositoryImpl.class;
}
- /** {@inheritDoc} */
- @Override protected Object getTargetRepository(RepositoryInformation metadata) {
- return getTargetRepositoryViaReflection(metadata, cache);
+ /**
+ * Evaluate the SpEL expression
+ *
+ * @param spelExpression SpEL expression
+ * @return the result of execution of the SpEL expression
+ */
+ private String evaluateExpression(String spelExpression) {
+ return (String)resolver.evaluate(spelExpression, beanExpressionContext);
}
/** {@inheritDoc} */
- @Override protected QueryLookupStrategy getQueryLookupStrategy(final QueryLookupStrategy.Key key,
- EvaluationContextProvider evaluationCtxProvider) {
+ @Override protected Object getTargetRepository(RepositoryInformation metadata) {
+ return getTargetRepositoryViaReflection(metadata, ignite, cache);
+ }
- return new QueryLookupStrategy() {
- @Override public RepositoryQuery resolveQuery(final Method mtd, final RepositoryMetadata metadata,
- final ProjectionFactory factory, NamedQueries namedQueries) {
+ /** {@inheritDoc} */
+ @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
+ QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ return Optional.of((mtd, metadata, factory, namedQueries) -> {
+ final Query annotation = mtd.getAnnotation(Query.class);
+ if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
+ .dynamicQuery())) {
- final Query annotation = mtd.getAnnotation(Query.class);
+ String qryStr = annotation.value();
- if (annotation != null) {
- String qryStr = annotation.value();
+ boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
+ .textQuery());
- if (key != Key.CREATE && StringUtils.hasText(qryStr))
- return new IgniteRepositoryQuery(metadata,
- new IgniteQuery(qryStr, isFieldQuery(qryStr), IgniteQueryGenerator.getOptions(mtd)),
- mtd, factory, cache);
+ IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
+ !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
+ annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
+
+ if (key != QueryLookupStrategy.Key.CREATE) {
+ return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
+ annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
+ evaluationContextProvider);
}
-
- if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY)
- throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass " +
- "a query string via org.apache.ignite.springdata.repository.config.Query annotation.");
-
- return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd,
- factory, cache);
}
- };
+
+ if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
+ throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
+ + "a query string via org.apache.ignite.springdata.repository"
+ + ".config.Query annotation.");
+ }
+
+ return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
+ cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
+ });
}
/**
* @param qry Query string.
- * @return {@code true} if query is SQLFieldsQuery.
+ * @return {@code true} if query is SqlFieldsQuery.
*/
- private boolean isFieldQuery(String qry) {
- return qry.matches("^SELECT.*") && !qry.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+ public static boolean isFieldQuery(String qry) {
+ String qryUpperCase = qry.toUpperCase();
+
+ return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+ }
+
+ /**
+ * Evaluates if the query starts with a clause.<br>
+ * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
+ *
+ * @param qryUpperCase Query string in upper case.
+ * @return {@code true} if query is full SQL statement.
+ */
+ private static boolean isStatement(String qryUpperCase) {
+ return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
+ // update
+ qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
+ // delete
+ qryUpperCase.matches("^\\s*DELETE\\b.*") ||
+ // merge
+ qryUpperCase.matches("^\\s*MERGE\\b.*") ||
+ // insert
+ qryUpperCase.matches("^\\s*INSERT\\b.*");
+ }
+
+ /**
+ * @return Configuration of the specified repository.
+ * @throws IllegalArgumentException If no configuration is specified.
+ * @see RepositoryConfig
+ */
+ static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
+ RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
+
+ Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
+ RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
+
+ return cfg;
}
}
-
-
-
-
-
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
index 3028cea..5b15ba5 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
@@ -19,47 +19,50 @@
import java.io.Serializable;
import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
import org.apache.ignite.springdata.repository.IgniteRepository;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
/**
* Apache Ignite repository factory bean.
- *
- * The repository requires to define one of the parameters below in your Spring application configuration in order
- * to get an access to Apache Ignite cluster:
+ * <p>
+ * The {@link RepositoryConfig} requires to define one of the
+ * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
* <ul>
- * <li>{@link Ignite} or {@link IgniteClient} instance bean named "igniteInstance"</li>
- * <li>{@link IgniteConfiguration} or {@link ClientConfiguration} bean named "igniteCfg"</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <li>{@link Ignite} instance bean</li>
+ * <li>{@link IgniteConfiguration} bean</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
* <ul/>
*
* @param <T> Repository type, {@link IgniteRepository}
- * @param <S> Domain object class.
- * @param <ID> Domain object key, super expects {@link Serializable}.
+ * @param <V> Domain object class.
+ * @param <K> Domain object key, super expects {@link Serializable}.
*/
-public class IgniteRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
- extends RepositoryFactoryBeanSupport<T, S, ID> {
- /** Ignite proxy. */
- @Autowired
- private IgniteProxy ignite;
+public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
+ extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
+ /** */
+ private ApplicationContext ctx;
/**
- * @param repositoryInterface Repository interface.
+ * @param repoInterface Repository interface.
*/
- protected IgniteRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
- super(repositoryInterface);
+ protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
+ super(repoInterface);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+ this.ctx = ctx;
}
/** {@inheritDoc} */
@Override protected RepositoryFactorySupport createRepositoryFactory() {
- return new IgniteRepositoryFactory(ignite, getObjectType());
+ return new IgniteRepositoryFactory(ctx, getObjectType());
}
}
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
index e8b8824..291877f 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
@@ -17,83 +17,154 @@
package org.apache.ignite.springdata.repository.support;
import java.io.Serializable;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import javax.cache.Cache;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
+import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
+import org.apache.ignite.springdata.proxy.IgniteProxy;
+import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
import org.apache.ignite.springdata.repository.IgniteRepository;
-
-import static java.util.Collections.emptySet;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.context.annotation.Conditional;
/**
- * General Apache Ignite repository implementation.
+ * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
+ * {@link IgniteRepositoryFactory}
+ *
+ * @param <V> the cache value type
+ * @param <K> the cache key type
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
*/
-public class IgniteRepositoryImpl<T, ID extends Serializable> implements IgniteRepository<T, ID> {
- /** Ignite Cache bound to the repository */
- private final IgniteCacheProxy<ID, T> cache;
+@Conditional(ConditionFalse.class)
+public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
+ /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
+ private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
+ " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
+
+ /**
+ * Ignite Cache bound to the repository
+ */
+ private final IgniteCacheProxy<K, V> cache;
+
+ /**
+ * Ignite instance bound to the repository
+ */
+ private final IgniteProxy ignite;
/**
* Repository constructor.
*
- * @param cache Initialized cache instance.
+ * @param ignite the ignite
+ * @param cache Initialized cache instance.
*/
- public IgniteRepositoryImpl(IgniteCacheProxy<ID, T> cache) {
+ public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
this.cache = cache;
+ this.ignite = ignite;
}
/** {@inheritDoc} */
- @Override public <S extends T> S save(ID key, S entity) {
+ @Override public IgniteCache<K, V> cache() {
+ if (cache instanceof IgniteNodeCacheProxy)
+ return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
+
+ throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Ignite ignite() {
+ if (ignite instanceof IgniteNodeProxy)
+ return ((IgniteNodeProxy)ignite).delegate();
+
+ throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <S extends V> S save(K key, S entity) {
cache.put(key, entity);
return entity;
}
/** {@inheritDoc} */
- @Override public <S extends T> Iterable<S> save(Map<ID, S> entities) {
+ @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
cache.putAll(entities);
return entities.values();
}
/** {@inheritDoc} */
- @Override public <S extends T> S save(S entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
+ @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
+ if (expiryPlc != null)
+ cache.withExpiryPolicy(expiryPlc).put(key, entity);
+ else
+ cache.put(key, entity);
+ return entity;
}
/** {@inheritDoc} */
- @Override public <S extends T> Iterable<S> save(Iterable<S> entities) {
+ @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
+ if (expiryPlc != null)
+ cache.withExpiryPolicy(expiryPlc).putAll(entities);
+ else
+ cache.putAll(entities);
+ return entities.values();
+ }
+
+ /**
+ * Not implemented.
+ */
+ @Override public <S extends V> S save(S entity) {
+ throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
+ }
+
+ /**
+ * Not implemented.
+ */
+ @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
}
/** {@inheritDoc} */
- @Override public T findOne(ID id) {
- return cache.get(id);
+ @Override public Optional<V> findById(K id) {
+ return Optional.ofNullable(cache.get(id));
}
/** {@inheritDoc} */
- @Override public boolean exists(ID id) {
+ @Override public boolean existsById(K id) {
return cache.containsKey(id);
}
/** {@inheritDoc} */
- @Override public Iterable<T> findAll() {
- final Iterator<Cache.Entry<ID, T>> iter = cache.iterator();
+ @Override public Iterable<V> findAll() {
+ final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
- return new Iterable<T>() {
- @Override public Iterator<T> iterator() {
- return new Iterator<T>() {
+ return new Iterable<V>() {
+ /** */
+ @Override public Iterator<V> iterator() {
+ return new Iterator<V>() {
+ /** {@inheritDoc} */
@Override public boolean hasNext() {
return iter.hasNext();
}
- @Override public T next() {
+ /** {@inheritDoc} */
+ @Override public V next() {
return iter.next().getValue();
}
+ /** {@inheritDoc} */
@Override public void remove() {
iter.remove();
}
@@ -102,37 +173,20 @@
};
}
- /**
- * @param ids Collection of IDs.
- * @return Collection transformed to set.
- */
- private Set<ID> toSet(Iterable<ID> ids) {
- if (ids instanceof Set)
- return (Set<ID>)ids;
-
- Iterator<ID> itr = ids.iterator();
-
- if (!itr.hasNext())
- return emptySet();
-
- ID key = itr.next();
-
- Set<ID> keys = key instanceof Comparable ? new TreeSet<>() : new HashSet<>();
-
- keys.add(key);
-
- while (itr.hasNext()) {
- key = itr.next();
-
- keys.add(key);
- }
-
- return keys;
- }
-
/** {@inheritDoc} */
- @Override public Iterable<T> findAll(Iterable<ID> ids) {
- return cache.getAll(toSet(ids)).values();
+ @Override public Iterable<V> findAllById(Iterable<K> ids) {
+ if (ids instanceof Set)
+ return cache.getAll((Set<K>)ids).values();
+
+ if (ids instanceof Collection)
+ return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
+
+ TreeSet<K> keys = new TreeSet<>();
+
+ for (K id : ids)
+ keys.add(id);
+
+ return cache.getAll(keys).values();
}
/** {@inheritDoc} */
@@ -141,23 +195,38 @@
}
/** {@inheritDoc} */
- @Override public void delete(ID id) {
+ @Override public void deleteById(K id) {
cache.remove(id);
}
/** {@inheritDoc} */
- @Override public void delete(T entity) {
- throw new UnsupportedOperationException("Use IgniteRepository.delete(key) method instead.");
+ @Override public void delete(V entity) {
+ throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
}
/** {@inheritDoc} */
- @Override public void delete(Iterable<? extends T> entities) {
- throw new UnsupportedOperationException("Use IgniteRepository.deleteAll(keys) method instead.");
+ @Override public void deleteAll(Iterable<? extends V> entities) {
+ throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
}
/** {@inheritDoc} */
- @Override public void deleteAll(Iterable<ID> ids) {
- cache.removeAll(toSet(ids));
+ @Override public void deleteAllById(Iterable<? extends K> ids) {
+ if (ids instanceof Set) {
+ cache.removeAll((Set<K>)ids);
+ return;
+ }
+
+ if (ids instanceof Collection) {
+ cache.removeAll(new HashSet<>((Collection<K>)ids));
+ return;
+ }
+
+ TreeSet<K> keys = new TreeSet<>();
+
+ for (K id : ids)
+ keys.add(id);
+
+ cache.removeAll(keys);
}
/** {@inheritDoc} */
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
index 749c9e7..58c5bb8 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
@@ -19,5 +19,4 @@
* <!-- Package description. -->
* Package contains supporting files required by Spring Data framework.
*/
-
package org.apache.ignite.springdata.repository.support;
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
index 6dcadb8..ec2e7ca 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.springdata;
+import org.apache.ignite.Ignite;
import org.apache.ignite.springdata.compoundkey.CityRepository;
import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -32,4 +33,9 @@
repo = ctx.getBean(CityRepository.class);
}
+
+ /** {@inheritDoc} */
+ @Override protected Ignite ignite() {
+ return ctx.getBean("igniteServerNode", Ignite.class);
+ }
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
index 751eb09..226ee9b 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
@@ -17,23 +17,30 @@
package org.apache.ignite.springdata;
-import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryWithCompoundKey;
+import org.apache.ignite.testframework.GridTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
/** {@inheritDoc} */
- @Override protected void beforeTestsStarted() {
+ @Override protected void beforeTestsStarted() throws Exception {
ctx = new AnnotationConfigApplicationContext();
ctx.register(IgniteClientApplicationConfiguration.class);
ctx.refresh();
repo = ctx.getBean(PersonRepository.class);
- repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
- ignite = ctx.getBean(IgniteEx.class);
+ }
+
+ /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
+ @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
+ GridTestUtils.assertThrows(log,
+ () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
+ "Query of type TextQuery is not supported by thin client. Check" +
+ " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
+ " method configuration or use Ignite node instance to connect to the Ignite cluster.");
}
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
index 0410e20..27d3645 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
@@ -20,6 +20,7 @@
import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
import org.apache.ignite.springdata.misc.Person;
import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
import org.apache.ignite.springdata.misc.PersonSecondRepository;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -34,10 +35,13 @@
repo = ctx.getBean(PersonRepository.class);
repo2 = ctx.getBean(PersonSecondRepository.class);
+ repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
for (int i = 0; i < CACHE_SIZE; i++) {
repo.save(i, new Person("person" + Integer.toHexString(i),
"lastName" + Integer.toHexString((i + 16) % 256)));
+ repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
+ "lastName" + Integer.toHexString((i + 16) % 256)));
}
}
}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
index 655ef40..d3ccf5e 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
@@ -19,8 +19,12 @@
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
import org.apache.ignite.Ignite;
import org.apache.ignite.springdata.compoundkey.City;
+import org.apache.ignite.springdata.compoundkey.CityKey;
import org.apache.ignite.springdata.compoundkey.CityRepository;
import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -48,12 +52,18 @@
/** Count Afganistan cities */
private static final int AFG_COUNT = 4;
+ /** Kabul identifier */
+ private static final int KABUL_ID = 1;
+
/** Quandahar identifier */
private static final int QUANDAHAR_ID = 2;
/** Afganistan county code */
private static final String AFG = "AFG";
+ /** test city Kabul */
+ protected static final City KABUL = new City("Kabul", "Kabol", 1780000);
+
/** test city Quandahar */
private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
@@ -78,7 +88,18 @@
loadData();
- assertEquals(TOTAL_COUNT, repo.count());
+ assertEquals(getTotalCount(), repo.count());
+ }
+
+ /**
+ * Clear data
+ * */
+ @Override protected void afterTest() throws Exception {
+ repo.deleteAll();
+
+ assertEquals(0, repo.count());
+
+ super.afterTest();
}
/**
@@ -88,9 +109,9 @@
ctx.close();
}
- /** load data*/
+ /** Load data. */
public void loadData() throws Exception {
- Ignite ignite = ctx.getBean(Ignite.class);
+ Ignite ignite = ignite();
if (ignite.cacheNames().contains(CACHE_NAME))
ignite.destroyCache(CACHE_NAME);
@@ -112,7 +133,32 @@
/** Test */
@Test
public void test() {
+ assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
}
+
+ /** Test. */
+ @Test
+ public void deleteAllById() {
+ Set<CityKey> keys = new HashSet<>();
+ keys.add(new CityKey(1, "AFG"));
+ keys.add(new CityKey(2, "AFG"));
+ keys.add(new CityKey(3, "AFG"));
+ keys.add(new CityKey(4, "AFG"));
+ keys.add(new CityKey(5, "NLD"));
+
+ repo.deleteAllById(keys);
+ assertEquals(0, repo.count());
+ }
+
+ /** */
+ protected Ignite ignite() {
+ return ctx.getBean(Ignite.class);
+ }
+
+ /** Total count of entries after load data. */
+ protected int getTotalCount() {
+ return TOTAL_COUNT;
+ }
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
index 5d5fbae..55d3fe6 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.springdata;
+import java.io.Serializable;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
@@ -28,12 +29,9 @@
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
import org.apache.ignite.springdata.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata.repository.support.IgniteProxyFactory;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -67,7 +65,7 @@
/** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
@Test
public void testRepositoryWithIgniteConfiguration() {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class);
+ checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
assertClientNodeIsStopped();
}
@@ -75,41 +73,41 @@
/** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
@Test
public void testRepositoryWithClientConfiguration() {
- checkRepositoryConfiguration(ClientConfigurationApplication.class);
+ checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
}
/** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
@Test
- public void testRepositoryWithNonDefaultIgniteBean() {
- checkRepositoryConfiguration(NonDefaultIgniteBeanApplication.class);
+ public void testRepositoryWithoutIgniteInstanceParameter() {
+ checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
}
/** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
@Test
- public void testRepositoryWithNonDefaultIgniteClientBean() {
- checkRepositoryConfiguration(NonDefaultIgniteClientBeanApplication.class);
+ public void testRepositoryWithoutIgniteClientInstanceParameter() {
+ checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
}
/** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
@Test
- public void testRepositoryWithNonDefaultIgniteClientConfigurationBean() {
- checkRepositoryConfiguration(NonDefaultIgniteClientConfigurationBeanApplication.class);
+ public void testRepositoryWithoutIgnitClientConfigurationParameter() {
+ checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
}
/** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
@Test
- public void testRepositoryWithNonDefaultIgniteConfigurationBean() {
- checkRepositoryConfiguration(NonDefaultIgniteConfigurationBeanApplication.class);
+ public void testRepositoryWithoutIgniteConfigurationParameter() {
+ checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
}
/**
* Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
- * is used to access the Ignite cluster.
+ * used to access the Ignite cluster.
*/
@Test
public void testRepositoryWithExistingIgniteInstance() throws Exception {
try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
- checkRepositoryConfiguration(IgniteConfigurationApplication.class);
+ checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
assertNotNull(Ignition.ignite(CLI_NAME));
}
@@ -128,9 +126,10 @@
return null;
},
IllegalArgumentException.class,
- "Invalid repository configuration [name=" + InvalidCacheRepository.class.getName() + "]. Set a" +
- " name of an Apache Ignite cache using org.apache.ignite.springdata.repository.config.RepositoryConfig" +
- " annotation to map this repository to the underlying cache.");
+ "Cache 'invalidCache' not found for repository interface" +
+ " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
+ " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
+ " org.apache.ignite.springdata.repository.config.RepositoryConfig annotation.");
}
assertClientNodeIsStopped();
@@ -159,21 +158,24 @@
* Checks that repository created based on specified Spring application configuration is properly initialized and
* got access to the Ignite cluster.
*/
- private void checkRepositoryConfiguration(Class<?> cfgCls) {
+ private void checkRepositoryConfiguration(
+ Class<?> cfgCls,
+ Class<? extends IgniteRepository<Object, Serializable>> repoCls
+ ) {
try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
ctx.register(cfgCls);
ctx.refresh();
- PersonRepository repo = ctx.getBean(PersonRepository.class);
+ IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
- IgniteCache<Integer, Person> cache = grid(SRV_NAME).cache(CACHE_NAME);
+ IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
assertEquals(0, repo.count());
assertEquals(0, cache.size());
int key = 0;
- repo.save(key, new Person("Domenico", "Scarlatti"));
+ repo.save(key, "1");
assertEquals(1, repo.count());
assertNotNull(cache.get(key));
@@ -185,11 +187,13 @@
* for accessing the cluster.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
- public static class IgniteConfigurationApplication {
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
+ public static class InvalidCacheNameApplication {
/** Ignite configuration bean. */
@Bean
- public IgniteConfiguration igniteCfg() {
+ public IgniteConfiguration igniteConfiguration() {
return getIgniteConfiguration(CLI_NAME, true);
}
}
@@ -201,11 +205,11 @@
@Configuration
@EnableIgniteRepositories(
considerNestedRepositories = true,
- includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheRepository.class))
- public static class InvalidCacheNameApplication {
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
+ public static class IgniteConfigurationApplication {
/** Ignite configuration bean. */
@Bean
- public IgniteConfiguration igniteCfg() {
+ public IgniteConfiguration igniteConfiguration() {
return getIgniteConfiguration(CLI_NAME, true);
}
}
@@ -215,22 +219,27 @@
* for accessing the cluster.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
public static class ClientConfigurationApplication {
/** Ignite client configuration bean. */
@Bean
- public ClientConfiguration igniteCfg() {
+ public ClientConfiguration clientConfiguration() {
return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
}
}
/**
- * Spring Application configuration for repository testing in case {@link Ignite} bean with name different from
- * {@link IgniteProxyFactory#IGNITE_INSTANCE_BEAN_NAME} is used for accessing the cluster.
+ * Spring Application configuration for repository testing in case if Ignite bean name was not provided
+ * through {@link RepositoryConfig#igniteInstance()} ()}.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
- public static class NonDefaultIgniteBeanApplication {
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+ )
+ public static class DefaultIgniteBeanApplication {
/** Ignite bean. */
@Bean
public Ignite someIgnite() {
@@ -239,12 +248,15 @@
}
/**
- * Spring Application configuration for repository testing in case {@link IgniteClient} bean with name different from
- * {@link IgniteProxyFactory#IGNITE_INSTANCE_BEAN_NAME} is used for accessing the cluster.
+ * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
+ * through {@link RepositoryConfig#igniteInstance()} ()}.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
- public static class NonDefaultIgniteClientBeanApplication {
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+ )
+ public static class DefaultIgniteClientBeanApplication {
/** Ignite client bean. */
@Bean
public IgniteClient someIgnite() {
@@ -253,12 +265,15 @@
}
/**
- * Spring Application configuration for repository testing in case {@link ClientConfiguration} bean with name different from
- * {@link IgniteProxyFactory#IGNITE_CONFIG_BEAN_NAME} is used for accessing the cluster.
+ * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
+ * through {@link RepositoryConfig#igniteCfg()}.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
- public static class NonDefaultIgniteClientConfigurationBeanApplication {
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+ )
+ public static class DefaultIgniteClientConfigurationBeanApplication {
/** Ignite client configuration bean. */
@Bean
public ClientConfiguration someCfg() {
@@ -267,12 +282,15 @@
}
/**
- * Spring Application configuration for repository testing in case {@link IgniteConfiguration} bean with name different from
- * {@link IgniteProxyFactory#IGNITE_CONFIG_BEAN_NAME} is used for accessing the cluster.
+ * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
+ * through {@link RepositoryConfig#igniteCfg()}.
*/
@Configuration
- @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
- public static class NonDefaultIgniteConfigurationBeanApplication {
+ @EnableIgniteRepositories(
+ considerNestedRepositories = true,
+ includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+ )
+ public static class DefaultIgniteConfigurationBeanApplication {
/** Ignite client configuration bean. */
@Bean
public IgniteConfiguration someCfg() {
@@ -280,9 +298,27 @@
}
}
- /** Repository for testing application behavior in case the cache name is not specified in the repository configuration. */
- @RepositoryConfig
- interface InvalidCacheRepository extends IgniteRepository<Person, Integer> {
+ /** Repository for testing configuration approach through default ignite beans. */
+ @RepositoryConfig(cacheName = "PersonCache")
+ public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
+ // No-op.
+ }
+
+ /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
+ @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
+ public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
+ // No-op.
+ }
+
+ /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
+ @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
+ public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
+ // No-op.
+ }
+
+ /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
+ @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
+ public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
// No-op.
}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
index 3f8cecc..a543044 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -21,55 +21,41 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Optional;
import java.util.TreeSet;
-import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.processors.query.RunningQueryManager;
-import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.FullNameProjection;
import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonKey;
+import org.apache.ignite.springdata.misc.PersonProjection;
import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryWithCompoundKey;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* CRUD tests.
*/
public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
- /** Number of entries to store. */
- protected static final int CACHE_SIZE = 1000;
+ /** Repository. */
+ protected static PersonRepository repo;
/** Context. */
protected static AnnotationConfigApplicationContext ctx;
- /** Repository. */
- protected static PersonRepository repo;
-
- /** Repository. */
- protected static PersonRepositoryWithCompoundKey repoWithCompoundKey;
-
- /** */
- @Rule
- public final ExpectedException expected = ExpectedException.none();
-
- /** */
- protected static IgniteEx ignite;
+ /** Number of entries to store */
+ private static int CACHE_SIZE = 1000;
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
ctx = new AnnotationConfigApplicationContext();
+
ctx.register(ApplicationConfiguration.class);
+
ctx.refresh();
repo = ctx.getBean(PersonRepository.class);
- repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
- ignite = ctx.getBean(IgniteEx.class);
}
/** {@inheritDoc} */
@@ -90,8 +76,22 @@
super.afterTest();
}
+ /** */
+ private void fillInRepository() {
+ for (int i = 0; i < CACHE_SIZE - 5; i++) {
+ repo.save(i, new Person("person" + Integer.toHexString(i),
+ "lastName" + Integer.toHexString((i + 16) % 256)));
+ }
+
+ repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ }
+
/** {@inheritDoc} */
- @Override protected void afterTestsStopped() {
+ @Override protected void afterTestsStopped() throws Exception {
ctx.destroy();
}
@@ -104,13 +104,18 @@
assertEquals(person, repo.save(id, person));
- assertTrue(repo.exists(id));
+ assertTrue(repo.existsById(id));
- assertEquals(person, repo.findOne(id));
+ assertEquals(person, repo.findById(id).get());
- expected.expect(UnsupportedOperationException.class);
- expected.expectMessage("Use IgniteRepository.save(key,value) method instead.");
- repo.save(person);
+ try {
+ repo.save(person);
+
+ fail("Managed to save a Person without ID");
+ }
+ catch (UnsupportedOperationException e) {
+ //excepted
+ }
}
/** */
@@ -130,11 +135,16 @@
while (persons.hasNext())
assertEquals(origPersons.next(), persons.next());
- expected.expect(UnsupportedOperationException.class);
- expected.expectMessage("Use IgniteRepository.save(Map<keys,value>) method instead.");
- repo.save(map.values());
+ try {
+ repo.saveAll(map.values());
- persons = repo.findAll(map.keySet()).iterator();
+ fail("Managed to save a list of Persons with ids");
+ }
+ catch (UnsupportedOperationException e) {
+ //expected
+ }
+
+ persons = repo.findAllById(map.keySet()).iterator();
int counter = 0;
@@ -168,19 +178,22 @@
public void testDelete() {
assertEquals(CACHE_SIZE, repo.count());
- repo.delete(0);
+ repo.deleteById(0);
assertEquals(CACHE_SIZE - 1, repo.count());
- assertNull(repo.findOne(0));
+ assertEquals(Optional.empty(),repo.findById(0));
- expected.expect(UnsupportedOperationException.class);
- expected.expectMessage("Use IgniteRepository.delete(key) method instead.");
- repo.delete(new Person("", ""));
+ try {
+ repo.delete(new Person("", ""));
+
+ fail("Managed to delete a Person without id");
+ }
+ catch (UnsupportedOperationException e) {
+ //expected
+ }
}
- /**
- *
- */
+ /** */
@Test
public void testDeleteSet() {
assertEquals(CACHE_SIZE, repo.count());
@@ -190,23 +203,26 @@
for (int i = 0; i < CACHE_SIZE / 2; i++)
ids.add(i);
- expected.expect(UnsupportedOperationException.class);
- expected.expectMessage("Use IgniteRepository.deleteAll(keys) method instead.");
- repo.deleteAll(ids);
+ repo.deleteAllById(ids);
assertEquals(CACHE_SIZE / 2, repo.count());
- ArrayList<Person> persons = new ArrayList<>();
+ try {
+ ArrayList<Person> persons = new ArrayList<>();
- for (int i = 0; i < 3; i++)
- persons.add(new Person(String.valueOf(i), String.valueOf(i)));
+ for (int i = 0; i < 3; i++)
+ persons.add(new Person(String.valueOf(i), String.valueOf(i)));
- repo.delete(persons);
+ repo.deleteAll(persons);
+
+ fail("Managed to delete Persons without ids");
+ }
+ catch (UnsupportedOperationException e) {
+ //expected
+ }
}
- /**
- *
- */
+ /** */
@Test
public void testDeleteAll() {
assertEquals(CACHE_SIZE, repo.count());
@@ -216,75 +232,216 @@
assertEquals(0, repo.count());
}
- /** */
- private void fillInRepository() {
- for (int i = 0; i < CACHE_SIZE; i++)
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
- }
-
- /** */
+ /**
+ * Delete existing record.
+ */
@Test
- public void shouldDeleteAll() {
- List<PersonKey> ids = prepareDataWithNonComparableKeys();
+ public void testDeleteByFirstName() {
+ assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
- repoWithCompoundKey.deleteAll(ids);
+ long cnt = repo.deleteByFirstName("uniquePerson");
- assertEquals(0, repoWithCompoundKey.count());
+ assertEquals(1, cnt);
}
- /** */
+ /**
+ * Delete NON existing record.
+ */
@Test
- public void shouldFindAll() {
- List<PersonKey> ids = prepareDataWithNonComparableKeys();
+ public void testDeleteExpression() {
+ long cnt = repo.deleteByFirstName("880");
- Iterable<Person> res = repoWithCompoundKey.findAll(ids);
-
- assertEquals(2, res.spliterator().estimateSize());
+ assertEquals(0, cnt);
}
- /** */
- private List<PersonKey> prepareDataWithNonComparableKeys() {
- List<PersonKey> ids = new ArrayList<>();
-
- PersonKey key = new PersonKey(1, 1);
- ids.add(key);
-
- repoWithCompoundKey.save(key, new Person("test1", "test1"));
-
- key = new PersonKey(2, 2);
- ids.add(key);
-
- repoWithCompoundKey.save(key, new Person("test2", "test2"));
-
- assertEquals(2, repoWithCompoundKey.count());
-
- return ids;
- }
-
- /** */
+ /**
+ * Delete Multiple records due to where.
+ */
@Test
- public void shouldNotLeakCursorsInRunningQueryManager() {
- RunningQueryManager runningQryMgr = ((IgniteH2Indexing)ignite.context().query().getIndexing()).runningQueryManager();
+ public void testDeleteExpressionMultiple() {
+ long count = repo.countByFirstName("nonUniquePerson");
+ long cnt = repo.deleteByFirstName("nonUniquePerson");
- assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ assertEquals(cnt, count);
+ }
- List<Person> res = repo.simpleQuery("person0");
+ /**
+ * Remove should do the same than Delete.
+ */
+ @Test
+ public void testRemoveExpression() {
+ repo.removeByFirstName("person3f");
- assertEquals(1, res.size());
+ long count = repo.count();
+ assertEquals(CACHE_SIZE - 1, count);
+ }
- assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ /**
+ * Delete unique record using lower case key word.
+ */
+ @Test
+ public void testDeleteQuery() {
+ repo.deleteBySecondNameLowerCase("uniqueLastName");
- Person person = repo.findTopBySecondNameStartingWith("lastName");
+ long countAfter = repo.count();
+ assertEquals(CACHE_SIZE - 1, countAfter);
+ }
- assertNotNull(person);
+ /**
+ * Try to delete with a wrong @Query.
+ */
+ @Test
+ public void testWrongDeleteQuery() {
+ long countBefore = repo.countByFirstNameLike("person3f");
- assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ try {
+ repo.deleteWrongByFirstNameQuery("person3f");
+ }
+ catch (Exception e) {
+ //expected
+ }
- long cnt = repo.countByFirstName("person0");
+ long countAfter = repo.countByFirstNameLike("person3f");
+ assertEquals(countBefore, countAfter);
+ }
+
+ /**
+ * Update with a @Query a record.
+ */
+ @Test
+ public void testUpdateQueryMixedCase() {
+ final String newSecondName = "updatedUniqueSecondName";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
assertEquals(1, cnt);
- assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+ List<Person> person = repo.findByFirstName("uniquePerson");
+ assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
+ }
+
+ /**
+ * Update with a @Query a record
+ */
+ @Test
+ public void testUpdateQueryMixedCaseProjection() {
+ final String newSecondName = "updatedUniqueSecondName1";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseProjectionNamedParameter() {
+ final String newSecondName = "updatedUniqueSecondName2";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
+ final String newSecondName = "updatedUniqueSecondName2";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+
+ List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
+ assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
+ final String newSecondName = "updatedUniqueSecondName2";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
+ assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
+
+ FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
+ assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
+ final String newSecondName = "updatedUniqueSecondName3";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
+ final String newSecondName = "updatedUniqueSecondName4";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
+ final String newSecondName = "updatedUniqueSecondName5";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
+ }
+
+ /** */
+ @Test
+ public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
+ final String newSecondName = "updatedUniqueSecondName6";
+ int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
+ assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
+ assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
+ }
+
+ /**
+ * Update with a wrong @Query
+ */
+ @Test
+ public void testWrongUpdateQuery() {
+ final String newSecondName = "updatedUniqueSecondName";
+ int rowsUpdated = 0;
+
+ try {
+ rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
+ }
+ catch (Exception ignored) {
+ //expected
+ }
+
+ assertEquals(0, rowsUpdated);
+
+ List<Person> person = repo.findByFirstName("uniquePerson");
+ assertEquals(person.get(0).getSecondName(), "uniqueLastName");
}
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
index 39568f9..19a9f63 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
@@ -20,10 +20,13 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import javax.cache.Cache;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonProjection;
import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
import org.apache.ignite.springdata.misc.PersonSecondRepository;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
@@ -42,12 +45,22 @@
/** Repository 2. */
protected static PersonSecondRepository repo2;
+ /**
+ * Repository Ignite Instance cluster TWO.
+ */
+ protected static PersonRepositoryOtherIgniteInstance repoTWO;
+
/** Context. */
protected static AnnotationConfigApplicationContext ctx;
- /** Number of entries to store */
+ /**
+ * Number of entries to store
+ */
protected static int CACHE_SIZE = 1000;
+ /**
+ * Performs context initialization before tests.
+ */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
@@ -59,13 +72,20 @@
repo = ctx.getBean(PersonRepository.class);
repo2 = ctx.getBean(PersonSecondRepository.class);
+ // repository on another ignite instance (and another cluster)
+ repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
- for (int i = 0; i < CACHE_SIZE; i++)
+ for (int i = 0; i < CACHE_SIZE; i++) {
repo.save(i, new Person("person" + Integer.toHexString(i),
"lastName" + Integer.toHexString((i + 16) % 256)));
+ repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
+ "lastName" + Integer.toHexString((i + 16) % 256)));
+ }
}
- /** {@inheritDoc} */
+ /**
+ * Performs context destroy after tests.
+ */
@Override protected void afterTestsStopped() throws Exception {
ctx.destroy();
}
@@ -83,6 +103,17 @@
/** */
@Test
+ public void testExplicitQueryTWO() {
+ List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
+
+ assertFalse(persons.isEmpty());
+
+ for (Person person : persons)
+ assertEquals("TWOperson4a", person.getFirstName());
+ }
+
+ /** */
+ @Test
public void testEqualsPart() {
List<Person> persons = repo.findByFirstName("person4e");
@@ -94,6 +125,17 @@
/** */
@Test
+ public void testEqualsPartTWO() {
+ List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
+
+ assertFalse(persons.isEmpty());
+
+ for (Person person : persons)
+ assertEquals("TWOperson4e", person.getFirstName());
+ }
+
+ /** */
+ @Test
public void testContainingPart() {
List<Person> persons = repo.findByFirstNameContaining("person4");
@@ -105,6 +147,17 @@
/** */
@Test
+ public void testContainingPartTWO() {
+ List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
+
+ assertFalse(persons.isEmpty());
+
+ for (Person person : persons)
+ assertTrue(person.getFirstName().startsWith("TWOperson4"));
+ }
+
+ /** */
+ @Test
public void testTopPart() {
Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
@@ -119,6 +172,20 @@
/** */
@Test
+ public void testTopPartTWO() {
+ Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
+
+ Iterator<Person> iter = top.iterator();
+
+ Person person = iter.next();
+
+ assertFalse(iter.hasNext());
+
+ assertTrue(person.getFirstName().startsWith("TWOperson4"));
+ }
+
+ /** */
+ @Test
public void testLikeAndLimit() {
Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
@@ -135,6 +202,22 @@
/** */
@Test
+ public void testLikeAndLimitTWO() {
+ Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
+
+ int cnt = 0;
+
+ for (Person next : like) {
+ assertTrue(next.getFirstName().contains("TWOperson"));
+
+ cnt++;
+ }
+
+ assertEquals(10, cnt);
+ }
+
+ /** */
+ @Test
public void testCount() {
int cnt = repo.countByFirstNameLike("person");
@@ -143,6 +226,14 @@
/** */
@Test
+ public void testCountTWO() {
+ int cnt = repoTWO.countByFirstNameLike("TWOperson");
+
+ assertEquals(1000, cnt);
+ }
+
+ /** */
+ @Test
public void testCount2() {
int cnt = repo.countByFirstNameLike("person4");
@@ -151,8 +242,16 @@
/** */
@Test
+ public void testCount2TWO() {
+ int cnt = repoTWO.countByFirstNameLike("TWOperson4");
+
+ assertTrue(cnt < 1000);
+ }
+
+ /** */
+ @Test
public void testPageable() {
- PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, "firstName");
+ PageRequest pageable = PageRequest.of(1, 5, Sort.Direction.DESC, "firstName");
HashSet<String> firstNames = new HashSet<>();
@@ -162,6 +261,7 @@
for (Person person : pageable1) {
firstNames.add(person.getFirstName());
+
assertTrue(person.getFirstName().matches("^[a-z]+$"));
}
@@ -171,6 +271,7 @@
for (Person person : pageable2) {
firstNames.add(person.getFirstName());
+
assertTrue(person.getFirstName().matches("^[a-z]+$"));
}
@@ -190,7 +291,7 @@
/** */
@Test
public void testQueryWithSort() {
- List<Person> persons = repo.queryWithSort("^[a-z]+$", new Sort(Sort.Direction.DESC, "secondName"));
+ List<Person> persons = repo.queryWithSort("^[a-z]+$", Sort.by(Sort.Direction.DESC, "secondName"));
Person previous = persons.get(0);
@@ -206,7 +307,7 @@
/** */
@Test
public void testQueryWithPaging() {
- List<Person> persons = repo.queryWithPageable("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+ List<Person> persons = repo.queryWithPageable("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
assertEquals(7, persons.size());
@@ -224,7 +325,7 @@
/** */
@Test
public void testQueryFields() {
- List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+ List<String> persons = repo.selectField("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
assertEquals(7, persons.size());
}
@@ -253,17 +354,17 @@
/** */
@Test
public void testFindOneValue() {
- Person person = repo.findTopBySecondNameStartingWith("lastName18");
+ PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
assertNotNull(person);
- assertTrue(person.getSecondName().startsWith("lastName18"));
+ assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
}
/** */
@Test
public void testSelectSeveralFields() {
- List<List> lists = repo.selectSeveralField("^[a-z]+$", new PageRequest(2, 6));
+ List<List> lists = repo.selectSeveralField("^[a-z]+$", PageRequest.of(2, 6));
assertEquals(6, lists.size());
@@ -285,7 +386,7 @@
/** */
@Test
public void testSliceOfCacheEntries() {
- Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
+ Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", PageRequest.of(3, 4));
assertEquals(4, slice.getSize());
@@ -296,7 +397,7 @@
/** */
@Test
public void testSliceOfLists() {
- Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new PageRequest(0, 3));
+ Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", PageRequest.of(0, 3));
assertEquals(3, lists.getSize());
@@ -307,14 +408,34 @@
}
}
+ /** Tests conversion of SQL select query result to domain entity objects. */
+ @Test
+ public void testRowToEntityConversion() {
+ Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
+
+ Set<Person> exp = new HashSet<>();
+
+ repo.findAll().forEach(exp::add);
+
+ assertEquals(exp, res);
+ }
+
/**
- * Tests the repository method with a custom query which takes no parameters.
+ * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
+ * of domain entity class.
*/
@Test
- public void testCountAllPersons() {
- int cnt = repo.countAllPersons();
+ public void testIncompleteRowToEntityConversion() {
+ Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
- assertEquals(CACHE_SIZE, cnt);
+ Set<Person> exp = new HashSet<>();
+
+ repo.findAll().forEach(p -> {
+ p.setSecondName(null);
+
+ exp.add(p);
+ });
+
+ assertEquals(exp, res);
}
}
-
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
index 691fe8e..1100594 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
@@ -25,7 +25,7 @@
/** City repository */
@Repository
-@RepositoryConfig(cacheName = "City")
+@RepositoryConfig(cacheName = "City", autoCreateCache = true)
public interface CityRepository extends IgniteRepository<City, CityKey> {
/**
* Find city by id
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
index ff1045e..075ff1b 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
@@ -23,28 +23,90 @@
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.spel.spi.EvaluationContextExtension;
-/**
- *
- */
+/** */
@Configuration
@EnableIgniteRepositories
public class ApplicationConfiguration {
+ /** */
+ public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
+
+ /** */
+ public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
+
/**
- * @return Ignite instance.
+ * The bean with cache names
+ */
+ @Bean
+ public CacheNamesBean cacheNames() {
+ CacheNamesBean bean = new CacheNamesBean();
+
+ bean.setPersonCacheName("PersonCache");
+
+ return bean;
+ }
+
+ /** */
+ @Bean
+ public EvaluationContextExtension sampleSpELExtension() {
+ return new SampleEvaluationContextExtension();
+ }
+
+ /** */
+ @Bean(value = "sampleExtensionBean")
+ public SamplePassParamExtension sampleExtensionBean() {
+ return new SamplePassParamExtension();
+ }
+
+ /**
+ * Ignite instance bean - no instance name provided on RepositoryConfig
*/
@Bean
public Ignite igniteInstance() {
- IgniteConfiguration cfg = new IgniteConfiguration()
- .setCacheConfiguration(
- new CacheConfiguration<Integer, Person>("PersonCache")
- .setIndexedTypes(Integer.class, Person.class),
- new CacheConfiguration<PersonKey, Person>("PersonWithKeyCache")
- )
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)));
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+ cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
+
+ CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+ ccfg.setIndexedTypes(Integer.class, Person.class);
+
+ cfg.setCacheConfiguration(ccfg);
+
+ TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+ spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+ cfg.setDiscoverySpi(spi);
+
+ return Ignition.start(cfg);
+ }
+
+ /**
+ * Ignite instance bean with not default name
+ */
+ @Bean
+ public Ignite igniteInstanceTWO() {
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+ cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
+
+ CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+ ccfg.setIndexedTypes(Integer.class, Person.class);
+
+ cfg.setCacheConfiguration(ccfg);
+
+ TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+ spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+ cfg.setDiscoverySpi(spi);
return Ignition.start(cfg);
}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
index 5044aef..f555e67 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
@@ -20,38 +20,84 @@
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.BinaryConfiguration;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.ClientConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.spel.spi.EvaluationContextExtension;
import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
+import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
+import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
/** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
@Configuration
@EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
public class IgniteClientApplicationConfiguration {
- /** @return {@link Ignite} node instance. */
- @Bean
- public IgniteEx igniteServerNode() {
- IgniteConfiguration cfg = new IgniteConfiguration()
- .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
- .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
- .setCacheConfiguration(new CacheConfiguration<Integer, Person>("PersonCache")
- .setIndexedTypes(Integer.class, Person.class));
+ /** Test cache name. */
+ public static final String CACHE_NAME = "PersonCache";
- return (IgniteEx)Ignition.start(cfg);
+ /** */
+ @Bean
+ public CacheNamesBean cacheNames() {
+ CacheNamesBean bean = new CacheNamesBean();
+
+ bean.setPersonCacheName(CACHE_NAME);
+
+ return bean;
+ }
+
+ /** */
+ @Bean
+ public EvaluationContextExtension sampleSpELExtension() {
+ return new SampleEvaluationContextExtension();
+ }
+
+ /** */
+ @Bean(value = "sampleExtensionBean")
+ public SamplePassParamExtension sampleExtensionBean() {
+ return new SamplePassParamExtension();
+ }
+
+ /** */
+ @Bean
+ public Ignite igniteServerNode() {
+ return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
+ }
+
+ /** */
+ @Bean
+ public Ignite igniteSecondServerNode() {
+ return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
}
/** Ignite client instance bean with default name. */
@Bean
public IgniteClient igniteInstance() {
- return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT));
+ return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
+ .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
+ }
+
+ /** Ignite client instance bean with non-default name. */
+ @Bean
+ public IgniteClient igniteInstanceTWO() {
+ return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
+ }
+
+ /** */
+ private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
+ return new IgniteConfiguration()
+ .setIgniteInstanceName(igniteInstanceName)
+ .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
+ .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
+ .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
+ .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
}
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
index 154937f..62c3054 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
@@ -17,8 +17,10 @@
package org.apache.ignite.springdata.misc;
+import java.util.Date;
import java.util.Objects;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
/**
* DTO class.
@@ -26,12 +28,17 @@
public class Person {
/** First name. */
@QuerySqlField(index = true)
+ @QueryTextField
private String firstName;
/** Second name. */
@QuerySqlField(index = true)
private String secondName;
+ /** Birthday. */
+ @QuerySqlField
+ private Date birthday;
+
/**
* @param firstName First name.
* @param secondName Second name.
@@ -39,6 +46,7 @@
public Person(String firstName, String secondName) {
this.firstName = firstName;
this.secondName = secondName;
+ birthday = new Date();
}
/**
@@ -74,6 +82,7 @@
return "Person{" +
"firstName='" + firstName + '\'' +
", secondName='" + secondName + '\'' +
+ ", birthday='" + birthday + '\'' +
'}';
}
@@ -88,11 +97,12 @@
Person person = (Person)o;
return Objects.equals(firstName, person.firstName) &&
- Objects.equals(secondName, person.secondName);
+ Objects.equals(secondName, person.secondName) &&
+ Objects.equals(birthday, person.birthday);
}
/** {@inheritDoc} */
@Override public int hashCode() {
- return Objects.hash(firstName, secondName);
+ return Objects.hash(firstName, secondName, birthday);
}
}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
similarity index 87%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
index 8222eb3..4c5e0ca 100644
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
@@ -17,8 +17,8 @@
package org.apache.ignite.springdata.misc;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
/**
*
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
index d8444d1..4cb959d 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
@@ -20,12 +20,14 @@
import java.util.Collection;
import java.util.List;
+
import javax.cache.Cache;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.apache.ignite.springdata.repository.config.Query;
import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
+import org.springframework.data.repository.query.Param;
/**
* Test repository.
@@ -36,6 +38,36 @@
public List<Person> findByFirstName(String val);
/** */
+ @Query("firstName = ?")
+ public List<PersonProjection> queryByFirstNameWithProjection(String val);
+
+ /** */
+ @Query("firstName = :firstname")
+ public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
+
+ /** */
+ @Query("firstName = :firstname")
+ public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
+
+ /** */
+ @Query("firstName = :firstname")
+ public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
+
+ /** */
+ @Query("firstName = ?#{[1]}")
+ public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
+
+ /** */
+ @Query(textQuery = true, value = "#{#firstname}", limit = 2)
+ public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
+
+ @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
+ public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
+
+ @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
+ public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
+
+ /** */
public List<Person> findByFirstNameContaining(String val);
/** */
@@ -66,7 +98,7 @@
public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
/** */
- public Person findTopBySecondNameStartingWith(String val);
+ public PersonProjection findTopBySecondNameStartingWith(String val);
/** */
@Query("firstName = ?")
@@ -92,8 +124,36 @@
@Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
public int countQuery(String val);
- /** */
- @Query("SELECT count(*) FROM Person")
- public int countAllPersons();
-}
+ /** Top 3 query */
+ public List<Person> findTop3ByFirstName(String val);
+ /** Delete query */
+ public long deleteByFirstName(String firstName);
+
+ /** Remove Query */
+ public List<Person> removeByFirstName(String firstName);
+
+ /** Delete using @Query with keyword in lower-case */
+ @Query("delete FROM Person WHERE secondName = ?")
+ public void deleteBySecondNameLowerCase(String secondName);
+
+ /** Delete using @Query but with errors on the query */
+ @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
+ public void deleteWrongByFirstNameQuery(String firstName);
+
+ /** Update using @Query with keyword in mixed-case */
+ @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
+ public int setFixedSecondNameMixedCase(String secondName, String firstName);
+
+ /** Update using @Query but with errors on the query */
+ @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
+ public int setWrongFixedSecondName(String secondName, String firstName);
+
+ /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
+ @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
+ public List<Person> queryWithRowToEntityConversion();
+
+ /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
+ @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
+ public List<Person> queryWithIncompleteRowToEntityConversion();
+}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
similarity index 96%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
index 307556b..47d2aa9 100644
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
@@ -22,9 +22,9 @@
import java.util.List;
import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.Param;
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
index e868911..062303c 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
@@ -23,6 +23,6 @@
/**
* Test repository.
*/
-@RepositoryConfig(cacheName = "PersonWithKeyCache")
+@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
}
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
index a82e822..b2b70ec 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
@@ -18,6 +18,7 @@
package org.apache.ignite.springdata.misc;
import java.util.List;
+
import javax.cache.Cache;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.apache.ignite.springdata.repository.config.Query;
@@ -27,7 +28,7 @@
import org.springframework.data.domain.Slice;
/**
- *
+ * Test repository.
*/
@RepositoryConfig(cacheName = "PersonCache")
public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
similarity index 97%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
index 9db4343..0c54b41 100644
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
@@ -22,7 +22,7 @@
import org.springframework.data.spel.spi.EvaluationContextExtension;
/**
- * Sample EvaluationContext Extension for Spring Data 2.2
+ * Sample EvaluationContext Extension for Spring Data.
* <p>
* Use SpEl expressions into your {@code @Query} definitions.
* <p>
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
index 4a47568..5eb926e 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
@@ -20,8 +20,10 @@
import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
+import org.apache.ignite.springdata.IgniteSpringDataCompoundExtendedKeyTest;
import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
+import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
import org.junit.runner.RunWith;
@@ -34,7 +36,9 @@
@Suite.SuiteClasses({
IgniteSpringDataCrudSelfTest.class,
IgniteSpringDataQueriesSelfTest.class,
+ IgniteSpringDataCrudSelfExpressionTest.class,
IgniteSpringDataCompoundKeyTest.class,
+ IgniteSpringDataCompoundExtendedKeyTest.class,
IgniteSpringDataConnectionConfigurationTest.class,
IgniteClientSpringDataCrudSelfTest.class,
IgniteClientSpringDataQueriesSelfTest.class,
@@ -42,4 +46,3 @@
})
public class IgniteSpringDataTestSuite {
}
-
diff --git a/modules/spring-session-ext/pom.xml b/modules/spring-session-ext/pom.xml
index d0cb2c7..1a3b8b7 100644
--- a/modules/spring-session-ext/pom.xml
+++ b/modules/spring-session-ext/pom.xml
@@ -34,7 +34,6 @@
<url>http://ignite.apache.org</url>
<properties>
- <spring.version>5.3.8</spring.version>
<spring.session.version>2.5.0</spring.session.version>
<spring.security.version>5.5.0</spring.security.version>
<javax.annotation.version>1.3.2</javax.annotation.version>
@@ -53,15 +52,22 @@
</dependency>
<dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${ignite.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
@@ -82,7 +88,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
</dependency>
<dependency>
@@ -111,7 +117,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
<scope>test</scope>
</dependency>
@@ -126,7 +132,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
- <version>${spring.version}</version>
+ <version>${spring53.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ignite/ignite-indexing -->
diff --git a/parent/pom.xml b/parent/pom.xml
index ad06205..56a1eb3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -41,10 +41,8 @@
<ignite-spring-boot-autoconfigure-ext.version>1.1.0-SNAPSHOT</ignite-spring-boot-autoconfigure-ext.version>
<ignite-spring-boot-thin-client-autoconfigure-ext.version>1.1.0-SNAPSHOT</ignite-spring-boot-thin-client-autoconfigure-ext.version>
<ignite-spring-cache-ext.version>1.1.0-SNAPSHOT</ignite-spring-cache-ext.version>
- <ignite-spring-data-2.0-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-2.0-ext.version>
- <ignite-spring-data-2.2-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-2.2-ext.version>
+ <ignite-spring-data-ext.version>2.0.0-SNAPSHOT</ignite-spring-data-ext.version>
<ignite-spring-data-commons.version>1.2.0-SNAPSHOT</ignite-spring-data-commons.version>
- <ignite-spring-data-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-ext.version>
<ignite-spring-tx-ext.version>1.1.0-SNAPSHOT</ignite-spring-tx-ext.version>
<ignite-zookeeper-ip-finder-ext.version>1.0.0-SNAPSHOT</ignite-zookeeper-ip-finder-ext.version>
@@ -134,14 +132,10 @@
<snappy.version>1.1.7.2</snappy.version>
<spark.hadoop.version>2.6.5</spark.hadoop.version>
<spark.version>2.3.0</spark.version>
- <spring.data.version>1.13.23.RELEASE</spring.data.version> <!-- don't forget to update spring version -->
- <spring.version>4.3.26.RELEASE</spring.version><!-- don't forget to update spring-data version -->
- <spring.data-2.0.version>2.0.13.RELEASE</spring.data-2.0.version> <!-- don't forget to update spring-5.0 version -->
- <spring-5.0.version>5.0.16.RELEASE</spring-5.0.version><!-- don't forget to update spring-data-2.0 version -->
- <spring.data-2.2.version>2.2.3.RELEASE</spring.data-2.2.version> <!-- don't forget to update spring-5.2 version -->
- <spring-5.2.version>5.2.3.RELEASE</spring-5.2.version><!-- don't forget to update spring-data-2.2 version -->
- <spring41.osgi.feature.version>4.1.7.RELEASE_1</spring41.osgi.feature.version>
- <spring-boot.version>2.2.2.RELEASE</spring-boot.version>
+ <spring.version>5.2.21.RELEASE</spring.version><!-- don't forget to update spring-data version -->
+ <spring.data.version>2.2.13.RELEASE</spring.data.version> <!-- don't forget to update spring version -->
+ <spring-boot.version>2.2.13.RELEASE</spring-boot.version>
+ <spring53.version>5.3.19</spring53.version>
<storm.version>1.1.1</storm.version>
<tomcat.version>9.0.10</tomcat.version>
<twitter.hbc.version>2.2.0</twitter.hbc.version>
@@ -354,14 +348,6 @@
<packages>org.apache.ignite.springdata.repository*</packages>
</group>
<group>
- <title>SpringData 2.0 integration</title>
- <packages>org.apache.ignite.springdata20.repository*</packages>
- </group>
- <group>
- <title>SpringData 2.2 integration</title>
- <packages>org.apache.ignite.springdata22.repository*</packages>
- </group>
- <group>
<title>RocketMQ integration</title>
<packages>org.apache.ignite.stream.rocketmq*</packages>
</group>
diff --git a/pom.xml b/pom.xml
index 2d2899c..e0531a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,8 +57,6 @@
<module>modules/jms11-ext</module>
<module>modules/kafka-ext</module>
<module>modules/spring-data-ext</module>
- <module>modules/spring-data-2.0-ext</module>
- <module>modules/spring-data-2.2-ext</module>
<module>modules/spring-data-commons</module>
<module>modules/performance-statistics-ext</module>
<module>modules/spring-tx-ext</module>
@@ -85,8 +83,7 @@
<modules>
<module>modules/spring-boot-autoconfigure-ext/examples</module>
<module>modules/spring-boot-thin-client-autoconfigure-ext/examples</module>
- <module>modules/spring-data-2.0-ext/examples</module>
- <module>modules/spring-data-2.2-ext/examples</module>
+ <module>modules/spring-data-ext/examples</module>
<module>modules/spring-tx-ext/examples</module>
<module>modules/zookeeper-ip-finder-ext/examples</module>
</modules>
@@ -157,18 +154,6 @@
</goals>
<phase>validate</phase>
<configuration>
- <additionalDependencies>
- <!--
- Only the last version of spring data is included to class path, some classes
- required by old spring data modules are absent in this version.
- Add spring-data-2.0 explicitly to be able to find all required classes.
- -->
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-commons</artifactId>
- <version>${spring.data-2.0.version}</version>
- </dependency>
- </additionalDependencies>
<reportOutputDirectory>${basedir}/target/javadoc</reportOutputDirectory>
<destDir>core</destDir>
<subpackages>org.apache.ignite -exclude org.apache.ignite.codegen:org.apache.ignite.examples:org.apache.ignite.internal:org.apache.ignite.schema:org.apache.ignite.tests:org.apache.ignite.tools:org.apache.ignite.util:org.apache.ignite.spi.discovery.tcp.messages:org.apache.ignite.spi.discovery.tcp.internal:org.apache.ignite.spi.communication.tcp.internal:org.apache.ignite.spi.discovery.zk.internal:org.apache.ignite.spi.deployment.uri.scanners:org.apache.ignite.spi.deployment.uri.tasks:org.apache.ignite.yardstick:org.apache.ignite.webtest</subpackages>