Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 33497200C62 for ; Wed, 12 Apr 2017 05:14:37 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 31D36160BA3; Wed, 12 Apr 2017 03:14:37 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 81626160B9B for ; Wed, 12 Apr 2017 05:14:35 +0200 (CEST) Received: (qmail 46399 invoked by uid 500); 12 Apr 2017 03:14:34 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 46390 invoked by uid 99); 12 Apr 2017 03:14:34 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Apr 2017 03:14:34 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 38378DF984; Wed, 12 Apr 2017 03:14:34 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: dmagda@apache.org To: commits@ignite.apache.org Date: Wed, 12 Apr 2017 03:14:33 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] ignite git commit: IGNITE-1192: Apache Ignite Spring Data integration archived-at: Wed, 12 Apr 2017 03:14:37 -0000 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: + *
    + *
  • {@link Ignite} instance bean named "igniteInstance"
  • + *
  • {@link IgniteConfiguration} bean named "igniteCfg"
  • + *
  • A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"
  • + *
      + * + * @param Repository type, {@link IgniteRepository} + * @param Domain object class. + * @param Domain object key, super expects {@link Serializable}. + */ +public class IgniteRepositoryFactoryBean, S, ID extends Serializable> + extends RepositoryFactoryBeanSupport 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 implements IgniteRepository { + /** Ignite Cache bound to the repository */ + private final IgniteCache cache; + + /** + * Repository constructor. + * + * @param cache Initialized cache instance. + */ + public IgniteRepositoryImpl(IgniteCache cache) { + this.cache = cache; + } + + /** {@inheritDoc} */ + @Override public S save(ID key, S entity) { + cache.put(key, entity); + + return entity; + } + + /** {@inheritDoc} */ + @Override public Iterable save(Map entities) { + cache.putAll(entities); + + return entities.values(); + } + + /** {@inheritDoc} */ + @Override public S save(S entity) { + throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead."); + } + + /** {@inheritDoc} */ + @Override public Iterable save(Iterable entities) { + throw new UnsupportedOperationException("Use IgniteRepository.save(Map) 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 findAll() { + final Iterator> iter = cache.iterator(); + + return new Iterable() { + @Override public Iterator iterator() { + return new Iterator() { + @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 findAll(Iterable ids) { + if (ids instanceof Set) + return cache.getAll((Set)ids).values(); + + if (ids instanceof Collection) + return cache.getAll(new HashSet<>((Collection)ids)).values(); + + TreeSet 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 entities) { + throw new UnsupportedOperationException("Use IgniteRepository.deleteAll(keys) method instead."); + } + + /** {@inheritDoc} */ + @Override public void deleteAll(Iterable ids) { + if (ids instanceof Set) + cache.removeAll((Set)ids); + + if (ids instanceof Collection) + cache.removeAll(new HashSet<>((Collection)ids)); + + TreeSet 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 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 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 persons = repo.save(map).iterator(); + + assertEquals(CACHE_SIZE + 50, repo.count()); + + Iterator 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 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 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 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 persons = repo.simpleQuery("person4a"); + + assertFalse(persons.isEmpty()); + + for (Person person : persons) + assertEquals("person4a", person.getFirstName()); + } + + /** */ + public void testEqualsPart() { + List persons = repo.findByFirstName("person4e"); + + assertFalse(persons.isEmpty()); + + for (Person person : persons) + assertEquals("person4e", person.getFirstName()); + } + + /** */ + public void testContainingPart() { + List persons = repo.findByFirstNameContaining("person4"); + + assertFalse(persons.isEmpty()); + + for (Person person : persons) + assertTrue(person.getFirstName().startsWith("person4")); + } + + /** */ + public void testTopPart() { + Iterable top = repo.findTopByFirstNameContaining("person4"); + + Iterator iter = top.iterator(); + + Person person = iter.next(); + + assertFalse(iter.hasNext()); + + assertTrue(person.getFirstName().startsWith("person4")); + } + + /** */ + public void testLikeAndLimit() { + Iterable 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 firstNames = new HashSet<>(); + + List 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 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 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 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 persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName")); + + assertEquals(7, persons.size()); + } + + /** */ + public void testFindCacheEntries() { + List> cacheEntries = repo.findBySecondNameLike("stName1"); + + assertFalse(cacheEntries.isEmpty()); + + for (Cache.Entry entry : cacheEntries) + assertTrue(entry.getValue().getSecondName().contains("stName1")); + } + + /** */ + public void testFindOneCacheEntry() { + Cache.Entry 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 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> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4)); + + assertEquals(4, slice.getSize()); + + for (Cache.Entry entry : slice) + assertFalse("lastName18".equals(entry.getValue().getSecondName())); + } + + /** */ + public void testSliceOfLists() { + Slice 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 { + /** */ + public List findByFirstName(String val); + + /** */ + public List findByFirstNameContaining(String val); + + /** */ + public List findByFirstNameRegex(String val, Pageable pageable); + + /** */ + public Collection findTopByFirstNameContaining(String val); + + /** */ + public Iterable findFirst10ByFirstNameLike(String val); + + /** */ + public int countByFirstNameLike(String val); + + /** */ + public int countByFirstNameLikeAndSecondNameLike(String like1, String like2); + + /** */ + public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2); + + /** */ + public List> findBySecondNameLike(String val); + + /** */ + public Cache.Entry findTopBySecondNameLike(String val); + + /** */ + public Person findTopBySecondNameStartingWith(String val); + + /** */ + @Query("firstName = ?") + public List simpleQuery(String val); + + /** */ + @Query("firstName REGEXP ?") + public List queryWithSort(String val, Sort sort); + + /** */ + @Query("SELECT * FROM Person WHERE firstName REGEXP ?") + public List queryWithPageable(String val, Pageable pageable); + + /** */ + @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?") + public List selectField(String val, Pageable pageable); + + /** */ + @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?") + public 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 { + /** */ + public Slice> findBySecondNameIsNot(String val, PageRequest pageReq); + + /** */ + @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?") + public Slice 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 @@ 2.4.1 2.1.0 4.1.0.RELEASE + 1.2.1.RELEASE UTF-8 MMMM d yyyy doxygen 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 @@ modules/extdata/uri modules/clients modules/spring + modules/spring-data modules/web modules/aop modules/urideploy