ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dma...@apache.org
Subject [1/2] ignite git commit: IGNITE-1192: Apache Ignite Spring Data integration
Date Wed, 12 Apr 2017 03:14:33 GMT
Repository: ignite
Updated Branches:
  refs/heads/master 55b9b8beb -> 4ad2657d4


http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
new file mode 100644
index 0000000..f4131ba
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
@@ -0,0 +1,85 @@
+/*
+ * 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.repository.support;
+
+import java.io.Serializable;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.springdata.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.
+ *
+ * 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:
+ * <ul>
+ * <li>{@link Ignite} instance bean named "igniteInstance"</li>
+ * <li>{@link IgniteConfiguration} bean named "igniteCfg"</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <ul/>
+ *
+ * @param <T> Repository type, {@link IgniteRepository}
+ * @param <S> Domain object class.
+ * @param <ID> Domain object key, super expects {@link Serializable}.
+ */
+public class IgniteRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends
Serializable>
+    extends RepositoryFactoryBeanSupport<T, S, ID> implements ApplicationContextAware
{
+    /** Application context. */
+    private ApplicationContext ctx;
+
+    /** {@inheritDoc} */
+    @Override public void setApplicationContext(ApplicationContext context) throws BeansException
{
+        this.ctx = context;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected RepositoryFactorySupport createRepositoryFactory() {
+        try {
+            Ignite ignite = (Ignite)ctx.getBean("igniteInstance");
+
+            return new IgniteRepositoryFactory(ignite);
+        }
+        catch (BeansException ex) {
+            try {
+                IgniteConfiguration cfg = (IgniteConfiguration)ctx.getBean("igniteCfg");
+
+                return new IgniteRepositoryFactory(cfg);
+            }
+            catch (BeansException ex2) {
+                try {
+                    String path = (String)ctx.getBean("igniteSpringCfgPath");
+
+                    return new IgniteRepositoryFactory(path);
+                }
+                catch (BeansException ex3) {
+                    throw new IgniteException("Failed to initialize Ignite repository factory.
Ignite instance or" +
+                        " IgniteConfiguration or a path to Ignite's spring XML configuration
must be defined in the" +
+                        " application configuration");
+                }
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
new file mode 100644
index 0000000..4290272
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
@@ -0,0 +1,160 @@
+/*
+ * 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.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.Set;
+import java.util.TreeSet;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+
+/**
+ * General Apache Ignite repository implementation.
+ */
+public class IgniteRepositoryImpl<T, ID extends Serializable> implements IgniteRepository<T,
ID> {
+    /** Ignite Cache bound to the repository */
+    private final IgniteCache<ID, T> cache;
+
+    /**
+     * Repository constructor.
+     *
+     * @param cache Initialized cache instance.
+     */
+    public IgniteRepositoryImpl(IgniteCache<ID, T> cache) {
+        this.cache = cache;
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> S save(ID key, S entity) {
+        cache.put(key, entity);
+
+        return entity;
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> Iterable<S> save(Map<ID, 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.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends T> Iterable<S> save(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);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean exists(ID id) {
+        return cache.containsKey(id);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<T> findAll() {
+        final Iterator<Cache.Entry<ID, T>> iter = cache.iterator();
+
+        return new Iterable<T>() {
+            @Override public Iterator<T> iterator() {
+                return new Iterator<T>() {
+                    @Override public boolean hasNext() {
+                        return iter.hasNext();
+                    }
+
+                    @Override public T next() {
+                        return iter.next().getValue();
+                    }
+
+                    @Override public void remove() {
+                        iter.remove();
+                    }
+                };
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<T> findAll(Iterable<ID> ids) {
+        if (ids instanceof Set)
+            return cache.getAll((Set<ID>)ids).values();
+
+        if (ids instanceof Collection)
+            return cache.getAll(new HashSet<>((Collection<ID>)ids)).values();
+
+        TreeSet<ID> keys = new TreeSet<>();
+
+        for (ID id : ids)
+            keys.add(id);
+
+        return cache.getAll(keys).values();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long count() {
+        return cache.size(CachePeekMode.PRIMARY);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(ID id) {
+        cache.remove(id);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(T entity) {
+        throw new UnsupportedOperationException("Use IgniteRepository.delete(key) method
instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void delete(Iterable<? extends T> entities) {
+        throw new UnsupportedOperationException("Use IgniteRepository.deleteAll(keys) method
instead.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void deleteAll(Iterable<ID> ids) {
+        if (ids instanceof Set)
+            cache.removeAll((Set<ID>)ids);
+
+        if (ids instanceof Collection)
+            cache.removeAll(new HashSet<>((Collection<ID>)ids));
+
+        TreeSet<ID> keys = new TreeSet<>();
+
+        for (ID id : ids)
+            keys.add(id);
+
+        cache.removeAll(keys);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void deleteAll() {
+        cache.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
new file mode 100644
index 0000000..95ab21d
--- /dev/null
+++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.springdata.repository.support;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
new file mode 100644
index 0000000..14d6844
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TreeMap;
+import java.util.TreeSet;
+import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+/**
+ *
+ */
+public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
+    /** Repository. */
+    private static PersonRepository repo;
+
+    /** Context. */
+    private 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();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        ctx.destroy();
+    }
+
+    /**
+     *
+     */
+    public void testPutGet() {
+        Person person = new Person("some_name", "some_surname");
+
+        int id = CACHE_SIZE + 1;
+
+        assertEquals(person, repo.save(id, person));
+
+        assertTrue(repo.exists(id));
+
+        assertEquals(person, repo.findOne(id));
+
+        try {
+            repo.save(person);
+
+            fail("Managed to save a Person without ID");
+        }
+        catch (UnsupportedOperationException e) {
+            //excepted
+        }
+    }
+
+    /**
+     *
+     */
+    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.save(map.values());
+
+            fail("Managed to save a list of Persons with ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+
+        persons = repo.findAll(map.keySet()).iterator();
+
+        int counter = 0;
+
+        while (persons.hasNext()) {
+            persons.next();
+            counter++;
+        }
+
+        assertEquals(map.size(), counter);
+    }
+
+    /**
+     *
+     */
+    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);
+    }
+
+    /**
+     *
+     */
+    public void testDelete() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        repo.delete(0);
+
+        assertEquals(CACHE_SIZE - 1, repo.count());
+        assertNull(repo.findOne(0));
+
+        try {
+            repo.delete(new Person("", ""));
+
+            fail("Managed to delete a Person without id");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+    }
+
+    /**
+     *
+     */
+    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.deleteAll(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.delete(persons);
+
+            fail("Managed to delete Persons without ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+    }
+
+    /**
+     *
+     */
+    public void testDeleteAll() {
+        assertEquals(CACHE_SIZE, repo.count());
+
+        repo.deleteAll();
+
+        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)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
new file mode 100644
index 0000000..40b7df2
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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 javax.cache.Cache;
+import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonSecondRepository;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+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. */
+    private static PersonRepository repo;
+
+    /** Repository 2. */
+    private static PersonSecondRepository repo2;
+
+    /** Context. */
+    private static AnnotationConfigApplicationContext ctx;
+
+    /** Number of entries to store */
+    private static int CACHE_SIZE = 1000;
+
+    @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);
+
+        for (int i = 0; i < CACHE_SIZE; i++)
+            repo.save(i, new Person("person" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+    }
+
+    @Override protected void afterTestsStopped() throws Exception {
+        ctx.destroy();
+
+        super.afterTestsStopped();
+    }
+
+    /** */
+    public void testExplicitQuery() {
+        List<Person> persons = repo.simpleQuery("person4a");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4a", person.getFirstName());
+    }
+
+    /** */
+    public void testEqualsPart() {
+        List<Person> persons = repo.findByFirstName("person4e");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("person4e", person.getFirstName());
+    }
+
+    /** */
+    public void testContainingPart() {
+        List<Person> persons = repo.findByFirstNameContaining("person4");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertTrue(person.getFirstName().startsWith("person4"));
+    }
+
+    /** */
+    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"));
+    }
+
+    /** */
+    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);
+    }
+
+    /** */
+    public void testCount() {
+        int cnt = repo.countByFirstNameLike("person");
+
+        assertEquals(1000, cnt);
+    }
+
+    /** */
+    public void testCount2() {
+        int cnt = repo.countByFirstNameLike("person4");
+
+        assertTrue(cnt < 1000);
+    }
+
+    /** */
+    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());
+    }
+
+    /** */
+    public void testAndAndOr() {
+        int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
+
+        int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1",
"lastName1");
+
+        assertTrue(cntAnd <= cntOr);
+    }
+
+    /** */
+    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;
+        }
+    }
+
+    /** */
+    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;
+        }
+    }
+
+    /** */
+    public void testQueryFields() {
+        List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC,
"secondName"));
+
+        assertEquals(7, persons.size());
+    }
+
+    /** */
+    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"));
+    }
+
+    /** */
+    public void testFindOneCacheEntry() {
+        Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
+
+        assertNotNull(cacheEntry);
+
+        assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
+    }
+
+    /** */
+    public void testFindOneValue() {
+        Person person = repo.findTopBySecondNameStartingWith("lastName18");
+
+        assertNotNull(person);
+
+        assertTrue(person.getSecondName().startsWith("lastName18"));
+    }
+
+    /** */
+    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);
+        }
+    }
+
+    /** */
+    public void testCountQuery() {
+        int cnt = repo.countQuery(".*");
+
+        assertEquals(256, cnt);
+    }
+
+    /** */
+    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()));
+    }
+
+    /** */
+    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);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
new file mode 100644
index 0000000..731e6d9
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * 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.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+
+/**
+ *
+ */
+@Configuration
+@EnableIgniteRepositories
+public class ApplicationConfiguration {
+    @Bean
+    public Ignite igniteInstance() {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+        ccfg.setIndexedTypes(Integer.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return Ignition.start(cfg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
new file mode 100644
index 0000000..a0adde5
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/Person.java
@@ -0,0 +1,97 @@
+/*
+ * 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.cache.query.annotations.QuerySqlField;
+
+public class Person {
+    /** First name. */
+    @QuerySqlField(index = true)
+    private String firstName;
+
+    /** Second name. */
+    @QuerySqlField(index = true)
+    private String secondName;
+
+    /**
+     * @param firstName First name.
+     * @param secondName Second name.
+     */
+    public Person(String firstName, String secondName) {
+        this.firstName = firstName;
+        this.secondName = secondName;
+    }
+
+    /**
+     *
+     */
+    public String getFirstName() {
+        return firstName;
+    }
+
+    /**
+     * @param firstName First name.
+     */
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    /**
+     *
+     */
+    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 + '\'' +
+            '}';
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        Person person = (Person)o;
+
+        if (firstName != null ? !firstName.equals(person.firstName) : person.firstName !=
null)
+            return false;
+        return secondName != null ? secondName.equals(person.secondName) : person.secondName
== null;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = firstName != null ? firstName.hashCode() : 0;
+        result = 31 * result + (secondName != null ? secondName.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
new file mode 100644
index 0000000..88f47d9
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
@@ -0,0 +1,92 @@
+
+/*
+ * 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.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.apache.ignite.springdata.repository.IgniteRepository;
+
+/**
+ *
+ */
+@RepositoryConfig(cacheName = "PersonCache")
+public interface PersonRepository extends IgniteRepository<Person, Integer> {
+    /** */
+    public List<Person> findByFirstName(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 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 Person 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);
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
new file mode 100644
index 0000000..a82e822
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
@@ -0,0 +1,40 @@
+/*
+ * 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.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.data.domain.AbstractPageRequest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+
+/**
+ *
+ */
+@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);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
new file mode 100644
index 0000000..0d6c519
--- /dev/null
+++ b/modules/spring-data/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
+import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
+
+/**
+ * Ignite Spring Data test suite.
+ */
+public class IgniteSpringDataTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Spring Data Test Suite");
+
+        suite.addTestSuite(IgniteSpringDataCrudSelfTest.class);
+        suite.addTestSuite(IgniteSpringDataQueriesSelfTest.class);
+
+        return suite;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index e3fa558..61bf077 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -38,6 +38,7 @@
         <hadoop.version>2.4.1</hadoop.version>
         <spark.version>2.1.0</spark.version>
         <spring.version>4.1.0.RELEASE</spring.version>
+        <spring.data.version>1.2.1.RELEASE</spring.data.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.build.timestamp.format>MMMM d yyyy</maven.build.timestamp.format>
         <doxygen.exec>doxygen</doxygen.exec>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4ad2657d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 41338dd..bc9b5d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,7 @@
         <module>modules/extdata/uri</module>
         <module>modules/clients</module>
         <module>modules/spring</module>
+        <module>modules/spring-data</module>
         <module>modules/web</module>
         <module>modules/aop</module>
         <module>modules/urideploy</module>


Mime
View raw message