IGNITE-1192: finished general key-value store implementation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b80b1a7b Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b80b1a7b Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b80b1a7b Branch: refs/heads/ignite-1192 Commit: b80b1a7b45340d31f4360967e66da5e9fac8c7ee Parents: cf27e54 Author: Denis Magda <[email protected]> Authored: Thu Mar 16 17:19:59 2017 -0700 Committer: Denis Magda <[email protected]> Committed: Thu Mar 16 17:19:59 2017 -0700 ---------------------------------------------------------------------- .../springdata/IgniteKeyValueAdapter.java | 56 +++++++- .../config/EnableIgniteRepositories.java | 136 +++++++++++++++++++ .../config/IgniteRepositoriesRegistar.java | 36 +++++ .../IgniteRepositoryConfigurationExtension.java | 40 ++++++ 4 files changed, 261 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/b80b1a7b/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java ---------------------------------------------------------------------- diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java index 5dbb286..bd299a9 100644 --- a/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java +++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/IgniteKeyValueAdapter.java @@ -18,8 +18,10 @@ package org.apache.ignite.springdata; import java.io.Serializable; -import java.util.Collection; +import java.util.AbstractMap; +import java.util.Iterator; import java.util.Map; +import javax.cache.Cache; import javax.cache.processor.EntryProcessor; import javax.cache.processor.EntryProcessorException; import javax.cache.processor.MutableEntry; @@ -27,10 +29,8 @@ import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteException; import org.apache.ignite.Ignition; -import org.apache.ignite.cache.CachePeekMode; import org.apache.ignite.configuration.IgniteConfiguration; import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.keyvalue.core.ForwardingCloseableIterator; import org.springframework.data.util.CloseableIterator; /** @@ -99,17 +99,59 @@ public class IgniteKeyValueAdapter extends AbstractKeyValueAdapter { /** {@inheritDoc} */ @Override public Object delete(Serializable id, Serializable keyspace) { - return cache(keyspace).invoke(id, new RemovalEntryProcessor()); + return cache(keyspace).invoke(id, new RemoveEntryProcessor()); } /** {@inheritDoc} */ @Override public Iterable<?> getAllOf(Serializable keyspace) { - return cache(keyspace).; + return new Iterable<Object>() { + @Override public Iterator<Object> iterator() { + return new CloseableIterator<Object>() { + Iterator<Cache.Entry<Serializable, Object>> iter = cache(keyspace).iterator(); + + @Override public boolean hasNext() { + return iter.hasNext(); + } + + @Override public Object next() { + Cache.Entry<Serializable, Object> entry = iter.next(); + + assert entry != null; + + return entry.getValue(); + } + + @Override public void close() { + // Ignite's internal iterator is referenced by a weak reference. Releasing it. + iter = null; + } + }; + } + }; } /** {@inheritDoc} */ @Override public CloseableIterator<Map.Entry<Serializable, Object>> entries(Serializable keyspace) { - return new ForwardingCloseableIterator<Map.Entry<Serializable, Object>>(cache(keyspace).iterator()); + return new CloseableIterator<Map.Entry<Serializable, Object>>() { + Iterator<Cache.Entry<Serializable, Object>> iter = cache(keyspace).iterator(); + + @Override public boolean hasNext() { + return iter.hasNext(); + } + + @Override public Map.Entry<Serializable, Object> next() { + Cache.Entry<Serializable, Object> entry = iter.next(); + + assert entry != null; + + return new AbstractMap.SimpleEntry<Serializable, Object>(entry.getKey(), entry.getValue()); + } + + @Override public void close() { + // Ignite's internal iterator is referenced by a weak reference. Releasing it. + iter = null; + } + }; } /** {@inheritDoc} */ @@ -149,7 +191,7 @@ public class IgniteKeyValueAdapter extends AbstractKeyValueAdapter { /** * */ - private static class RemovalEntryProcessor implements EntryProcessor<Serializable, Object, Object> { + private static class RemoveEntryProcessor implements EntryProcessor<Serializable, Object, Object> { /** {@inheritDoc} */ @Override public Object process(MutableEntry<Serializable, Object> entry, Object... arguments) throws EntryProcessorException { http://git-wip-us.apache.org/repos/asf/ignite/blob/b80b1a7b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java ---------------------------------------------------------------------- diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java new file mode 100644 index 0000000..0705e88 --- /dev/null +++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java @@ -0,0 +1,136 @@ +/* + * 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.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.springframework.beans.factory.FactoryBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Import; +import org.springframework.data.keyvalue.core.KeyValueOperations; +import org.springframework.data.keyvalue.core.KeyValueTemplate; +import org.springframework.data.keyvalue.repository.config.QueryCreatorType; +import org.springframework.data.keyvalue.repository.query.CachingKeyValuePartTreeQuery; +import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; +import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; +import org.springframework.data.repository.config.DefaultRepositoryBaseClass; +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. + * + * TODO: replace QueryCreatorType with Ignite version of the querying engine. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@Import(IgniteRepositoriesRegistar.class) +@QueryCreatorType(value = SpelQueryCreator.class, repositoryQueryType = CachingKeyValuePartTreeQuery.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 + */ + String repositoryImplementationPostfix() default "Impl"; + + /** + * Configures the location of where to find the Spring Data named queries properties file. + * + * @return + */ + 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 queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; + + /** + * TODO: replace with Ignite factory bean. + * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to + * {@link KeyValueRepositoryFactoryBean}. + * + * @return + */ + Class<?> repositoryFactoryBeanClass() default KeyValueRepositoryFactoryBean.class; + + /** + * Configure the repository base class to be used to create repository proxies for this particular configuration. + * + * @return + */ + Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class; + + /** + * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories detected. + * + * @return + */ + String keyValueTemplateRef() default "igniteKeyValueTemplate"; + + /** + * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the + * repositories infrastructure. + */ + boolean considerNestedRepositories() default false; +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b80b1a7b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java ---------------------------------------------------------------------- diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java new file mode 100644 index 0000000..0f65c32 --- /dev/null +++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java @@ -0,0 +1,36 @@ +/* + * 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.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(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b80b1a7b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java ---------------------------------------------------------------------- diff --git a/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java new file mode 100644 index 0000000..30f9385 --- /dev/null +++ b/modules/spring-data/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.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.repository.config; + +import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}. + */ +public class IgniteRepositoryConfigurationExtension extends KeyValueRepositoryConfigurationExtension { + /** {@inheritDoc} */ + @Override public String getModuleName() { + return "Apache Ignite"; + } + + /** {@inheritDoc} */ + @Override protected String getModulePrefix() { + return "ignite"; + } + + /** {@inheritDoc} */ + @Override protected String getDefaultKeyValueTemplateRef() { + return "igniteKeyValueTemplate"; + } +}
