SGF-402 - Polish.
(cherry picked from commit 479bc4e3253425b60d01d1ee4b346d971db3a9e9) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -177,6 +177,8 @@ javadoc {
|
||||
links = [
|
||||
"http://docs.oracle.com/javase/6/docs/api/",
|
||||
"http://docs.spring.io/spring/docs/current/javadoc-api/",
|
||||
"http://docs.spring.io/spring-data-gemfire/docs/current/api/",
|
||||
"http://docs.spring.io/spring-data/commons/docs/current/api/index.html?index-all.html",
|
||||
"http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/",
|
||||
"http://logging.apache.org/log4j/1.2/apidocs/",
|
||||
]
|
||||
|
||||
7
pom.xml
7
pom.xml
@@ -80,16 +80,13 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<<<<<<< HEAD
|
||||
<groupId>io.pivotal.gemfire</groupId>
|
||||
=======
|
||||
<groupId>org.apache.geode</groupId>
|
||||
<artifactId>geode-lucene</artifactId>
|
||||
<version>${gemfire.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.geode</groupId>
|
||||
>>>>>>> f104d57... SGF-402 - Add Lucene Integration support.
|
||||
<groupId>io.pivotal.gemfire</groupId>
|
||||
<artifactId>geode-wan</artifactId>
|
||||
<version>${gemfire.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -19,9 +19,9 @@ can be created in _Spring (Data GemFire)_ XML config like so...
|
||||
|
||||
Additionally, Apache Lucene allows the specification of
|
||||
http://lucene.apache.org/core/6_5_0/core/org/apache/lucene/analysis/Analyzer.html[Analyzers] per field
|
||||
and can be configured like so...
|
||||
and can be configured using...
|
||||
|
||||
[source.xml]
|
||||
[source,xml]
|
||||
----
|
||||
<gfe:lucene-index id="IndexTwo" lucene-service-ref="luceneService" region-path="/AnotherExample">
|
||||
<gfe:field-analyzers>
|
||||
@@ -37,10 +37,10 @@ and can be configured like so...
|
||||
</gfe:lucene-index>
|
||||
----
|
||||
|
||||
Of course, the `Map` can be specified at top-level bean definitions and referenced using the `ref` attribute
|
||||
on the `<gfe:field-analyzers>` element like this, `<gfe-field-analyzers ref="refToTopLevelMapBeanDefinition"/>`.
|
||||
Of course, the `Map` can be specified as a top-level bean definition and referenced using the `ref` attribute
|
||||
on the nested `<gfe:field-analyzers>` element like this, `<gfe-field-analyzers ref="refToTopLevelMapBeanDefinition"/>`.
|
||||
|
||||
Alternatively, a `LuceneIndex` can be declared in _Spring_ Java config, inside a `@Configuration` class like so...
|
||||
Alternatively, a `LuceneIndex` can be declared in _Spring_ Java config, inside a `@Configuration` class with...
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -73,12 +73,13 @@ be created on a Geode `PARTITION` Region. Second, all `LuceneIndexes` must be c
|
||||
the `LuceneIndex` is applied.
|
||||
|
||||
It is possible that these Apache Geode restrictions will not apply in a future release which is why
|
||||
the SDG `LuceneIndexFactoryBean` can take a reference to the Region directly rather than just the Region path,
|
||||
which is more ideal. For instance, it is reasonable to assume that some users may want to define a `LuceneIndex`
|
||||
on an already existing Region with data at a later point in the application lifecycle and as requirements demand.
|
||||
Where possible, SDG strives to stick to strongly-typed objects and classes.
|
||||
the SDG `LuceneIndexFactoryBean` API takes a reference to the Region directly as well, rather than just the Region path.
|
||||
|
||||
Now that we have a `LuceneIndex` we can perform Lucene based data access operations, such as queries and so on.
|
||||
This is more ideal if think about the case in which users may want to define a `LuceneIndex` on an existing Region
|
||||
with data at a later point during the application's lifecycle and as requirements demand. Where possible, SDG strives
|
||||
to stick to strongly-typed objects.
|
||||
|
||||
Now that we have a `LuceneIndex` we can perform Lucene based data access operations, such as queries.
|
||||
|
||||
#### Lucene Template Data Accessors
|
||||
|
||||
@@ -114,15 +115,17 @@ public interface LuceneOperations {
|
||||
}
|
||||
----
|
||||
|
||||
The operations in the `LuceneOperations` interface match the operations provided by the Apache Geode
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/lucene/LuceneQuery.html[LuceneQuery] interface,
|
||||
however SDG has the added value of translating proprietary Geode or Lucene `Exceptions` into _Spring's_ highly
|
||||
NOTE: The `[, int resultLimit]` indicates that the `resultLimit` parameter is optional.
|
||||
|
||||
The operations in the `LuceneOperations` interface match the operations provided by the Apache Geode's
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/lucene/LuceneQuery.html[LuceneQuery] interface.
|
||||
However, SDG has the added value of translating proprietary Geode or Lucene `Exceptions` into _Spring's_ highly
|
||||
consistent and expressive DAO
|
||||
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#dao-exceptions[Exception Hierarchy],
|
||||
particularly as many modern data access operations involve more than one store or repository.
|
||||
particularly as many modern data access operations involve more than single store or repository.
|
||||
|
||||
Additionally, SDG's `LuceneOperations` interface can shield your application from interface breaking changes
|
||||
introduced by the underlying Apache Geode or Apache Lucene APIs when they do and will change.
|
||||
introduced by the underlying Apache Geode or Apache Lucene APIs when they do and will occur.
|
||||
|
||||
However, it would be remorse to only offer a Lucene Data Access Object that only uses Apache Geode and Apache Lucene
|
||||
data types (e.g. Geode's `LuceneResultStruct`), therefore SDG gives you the `ProjectingLuceneOperations` interface
|
||||
@@ -143,7 +146,7 @@ public interface ProjectingLuceneOperations {
|
||||
----
|
||||
|
||||
The `ProjectingLuceneOperations` interface primarily uses application domain object types to work with
|
||||
your application data. The `query` method variants accept a "projection type" and the template applies
|
||||
your application data. The `query` method variants accept a projection type and the template applies
|
||||
the query results to instances of the given projection type using the _Spring Data Commons_
|
||||
Projection infrastructure.
|
||||
|
||||
@@ -172,7 +175,7 @@ class Person {
|
||||
}
|
||||
----
|
||||
|
||||
Additionally, I might have a single interface to represent people as Customers depending on my application view...
|
||||
Additionally, I might have a single interface to represent people as `Customers` depending on my application view...
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -205,7 +208,7 @@ Then it is a simple matter to query for people as either `Person` objects...
|
||||
List<Person> people = luceneTemplate.query("lastName: D*", "lastName", Person.class);
|
||||
----
|
||||
|
||||
Or as a page of type `Customer`...
|
||||
Or as a `Page` of type `Customer`...
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -222,19 +225,19 @@ List<Customer> firstPage = customers.getContent();
|
||||
Conveniently, the _Spring Data Commons_ `Page` interface implements `java.lang.Iterable<T>` too making it very easy
|
||||
to iterate over the content as well.
|
||||
|
||||
The only restriction to the _Spring Data Commons_ Projection infrastructure is that the "projection type"
|
||||
The only restriction to the _Spring Data Commons_ Projection infrastructure is that the projection type
|
||||
must be an interface. However, it is possible to extend the provided, out-of-the-box (OOTB)
|
||||
SDC Projection infrastructure and provide a "custom"
|
||||
SDC Projection infrastructure and provide a custom
|
||||
http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/projection/ProjectionFactory.html[ProjectionFactory]
|
||||
that uses https://github.com/cglib/cglib[CGLIB] to generate proxy classes as the projected entity.
|
||||
|
||||
The "custom" `ProjectionFactory` can then be set on the template using `setProjectionFactory(:ProjectionFactory)`.
|
||||
A custom `ProjectionFactory` can be set on a Lucene template using `setProjectionFactory(:ProjectionFactory)`.
|
||||
|
||||
#### Annotation configuration support
|
||||
|
||||
Finally, _Spring Data Geode_ provides Annotation configuration support for `LuceneIndexes`. Eventually, the SDG Lucene
|
||||
support will find its way into the Repository infrastructure extension for Apache Geode so that Lucene queries
|
||||
can be expressed as methods on an application Repository interface, much like the
|
||||
support will find its way into the _Repository_ infrastructure extension for Apache Geode so that Lucene queries
|
||||
can be expressed as methods on an application `Repository` interface, much like the
|
||||
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/#gemfire-repositories.executing-queries[OQL support]
|
||||
today.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[[bootstrap:snapshot]]
|
||||
= Using the GemFire Snapshot Service
|
||||
= Using the Snapshot Service
|
||||
|
||||
Spring Data GemFire supports `Cache` and `Region` snapshots using http://gemfire81.docs.pivotal.io/latest/userguide/index.html#managing/cache_snapshots/chapter_overview.html[GemFire's Snapshot Service].
|
||||
The out-of-the-box Snapshot Service support offers several convenient features to simply the use of GemFire's http://data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/snapshot/CacheSnapshotService.html[Cache]
|
||||
|
||||
@@ -197,7 +197,7 @@ public class Interest<K> implements InitializingBean {
|
||||
* using {@link Pattern#compile(String)}, then the {@code key} is considered a Regular Expression
|
||||
* and interest will be registered using {@link org.apache.geode.cache.Region#registerInterestRegex(String)}.
|
||||
*
|
||||
* @param key {@link String} to evaluate.
|
||||
* @param value {@link String} to evaluate.
|
||||
* @return a boolean value indicating whether the given {@link String} {@code value} is a Regular Expression.
|
||||
* @see #containsNonAlphaNumericWhitespace(String)
|
||||
* @see java.util.regex.Pattern#compile(String)
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
package org.springframework.data.gemfire.domain;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
/**
|
||||
@@ -56,7 +57,7 @@ public final class EmptyPage<T> extends EmptySlice<T> implements Page<T> {
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S> Page<S> map(Converter<? super T, ? extends S> converter) {
|
||||
public <S> Page<S> map(Function<? super T, ? extends S> converter) {
|
||||
return (Page<S>) EMPTY_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.springframework.data.gemfire.domain;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -104,7 +104,7 @@ public abstract class EmptySlice<T> extends AbstractSliceSupport<T> {
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S> Slice<S> map(Converter<? super T, ? extends S> converter) {
|
||||
public <S> Slice<S> map(Function<? super T, ? extends S> converter) {
|
||||
return (Slice<S>) EMPTY_SLICE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
* persistent entity will be stored.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.9.0
|
||||
@@ -92,8 +93,6 @@ public @interface ClientRegion {
|
||||
* Determines whether an entity annotated with this Region annotation will ignore any existing Region definition
|
||||
* identified by the given {@link #name()} for this entity.
|
||||
*
|
||||
* Overrides the global, {@link EnableEntityDefinedRegions#ignoreIfExists()} setting.
|
||||
*
|
||||
* Defaults to {@literal true}.
|
||||
*/
|
||||
boolean ignoreIfExists() default true;
|
||||
|
||||
@@ -26,13 +26,13 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
|
||||
/**
|
||||
* {@link Annotation} defining the Local {@link Region} in which the application persistent entity will be stored.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.9.0
|
||||
*/
|
||||
@@ -89,8 +89,6 @@ public @interface LocalRegion {
|
||||
* Determines whether an entity annotated with this Region annotation will ignore any existing Region definition
|
||||
* identified by the given {@link #name()} for this entity.
|
||||
*
|
||||
* Overrides the global, {@link EnableEntityDefinedRegions#ignoreIfExists()} setting.
|
||||
*
|
||||
* Defaults to {@literal true}.
|
||||
*/
|
||||
boolean ignoreIfExists() default true;
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.core.annotation.AliasFor;
|
||||
* {@link Annotation} defining the Partition {@link Region} in which the application persistent entity will be stored.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.9.0
|
||||
@@ -110,8 +111,6 @@ public @interface PartitionRegion {
|
||||
* Determines whether an entity annotated with this Region annotation will ignore any existing Region definition
|
||||
* identified by the given {@link #name()} for this entity.
|
||||
*
|
||||
* Overrides the global, {@link EnableEntityDefinedRegions#ignoreIfExists()} setting.
|
||||
*
|
||||
* Defaults to {@literal true}.
|
||||
*/
|
||||
boolean ignoreIfExists() default true;
|
||||
|
||||
@@ -75,8 +75,6 @@ public @interface Region {
|
||||
* Determines whether an entity annotated with this Region annotation will ignore any existing Region definition
|
||||
* identified by the given {@link #name()} for this entity.
|
||||
*
|
||||
* Overrides the global, {@link EnableEntityDefinedRegions#ignoreIfExists()} setting.
|
||||
*
|
||||
* Defaults to {@literal true}.
|
||||
*/
|
||||
boolean ignoreIfExists() default true;
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.data.gemfire.ScopeType;
|
||||
* {@link Annotation} defining the Replicate {@link Region} in which the application persistent entity will be stored.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Region
|
||||
* @since 1.9.0
|
||||
@@ -89,8 +90,6 @@ public @interface ReplicateRegion {
|
||||
* Determines whether an entity annotated with this Region annotation will ignore any existing Region definition
|
||||
* identified by the given {@link #name()} for this entity.
|
||||
*
|
||||
* Overrides the global, {@link EnableEntityDefinedRegions#ignoreIfExists()} setting.
|
||||
*
|
||||
* Defaults to {@literal true}.
|
||||
*/
|
||||
boolean ignoreIfExists() default true;
|
||||
|
||||
@@ -134,7 +134,7 @@ public abstract class LuceneAccessor extends LuceneOperationsSupport implements
|
||||
/**
|
||||
* Creates an instance of the {@link LuceneQueryFactory} to create and execute {@link LuceneQuery Lucene queries}.
|
||||
*
|
||||
* @param projectionFields {@link String[]} containing the fields of the object to project.
|
||||
* @param projectionFields {@link String} array containing the fields of the object to project.
|
||||
* @return an instance of the {@link LuceneQueryFactory} to create and execute {@link LuceneQuery Lucene queries}.
|
||||
* @see org.apache.geode.cache.lucene.LuceneQueryFactory
|
||||
* @see #createLuceneQueryFactory(int, int, String...)
|
||||
@@ -147,7 +147,7 @@ public abstract class LuceneAccessor extends LuceneOperationsSupport implements
|
||||
* Creates an instance of the {@link LuceneQueryFactory} to create and execute {@link LuceneQuery Lucene queries}.
|
||||
*
|
||||
* @param resultLimit limit to the number of results returned by the query.
|
||||
* @param projectionFields {@link String[]} containing the fields of the object to project.
|
||||
* @param projectionFields {@link String} array containing the fields of the object to project.
|
||||
* @return an instance of the {@link LuceneQueryFactory} to create and execute {@link LuceneQuery Lucene queries}.
|
||||
* @see org.apache.geode.cache.lucene.LuceneQueryFactory
|
||||
* @see #createLuceneQueryFactory(int, int, String...)
|
||||
@@ -161,7 +161,7 @@ public abstract class LuceneAccessor extends LuceneOperationsSupport implements
|
||||
*
|
||||
* @param resultLimit limit to the number of results returned by the query.
|
||||
* @param pageSize number of results appearing on a single page.
|
||||
* @param projectionFields {@link String[]} containing the fields of the object to project.
|
||||
* @param projectionFields {@link String} array containing the fields of the object to project.
|
||||
* @return an instance of the {@link LuceneQueryFactory} to create and execute {@link LuceneQuery Lucene queries}.
|
||||
* @see #createLuceneQueryFactory()
|
||||
*/
|
||||
|
||||
@@ -105,7 +105,6 @@ public class AbstractSliceSupportTests {
|
||||
Pageable mockPageable = mock(Pageable.class);
|
||||
|
||||
when(mockPageable.previousOrFirst()).thenReturn(mockPageable);
|
||||
when(mockPageable.hasPrevious()).thenReturn(false);
|
||||
doReturn(mockPageable).when(mockSlice).previousPageable();
|
||||
|
||||
assertThat(mockSlice.getNumber()).isEqualTo(2);
|
||||
@@ -120,9 +119,7 @@ public class AbstractSliceSupportTests {
|
||||
Pageable mockPageableTwo = mock(Pageable.class, "Page Two");
|
||||
|
||||
when(mockPageableOne.previousOrFirst()).thenReturn(mockPageableOne);
|
||||
when(mockPageableOne.hasPrevious()).thenReturn(false);
|
||||
when(mockPageableTwo.previousOrFirst()).thenReturn(mockPageableOne);
|
||||
when(mockPageableTwo.hasPrevious()).thenReturn(true);
|
||||
doReturn(mockPageableTwo).when(mockSlice).previousPageable();
|
||||
|
||||
assertThat(mockSlice.getNumber()).isEqualTo(3);
|
||||
|
||||
@@ -46,7 +46,7 @@ import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.data.gemfire.search.lucene.support.LuceneAccessorSupport;
|
||||
|
||||
@@ -60,7 +60,7 @@ import org.springframework.data.gemfire.search.lucene.support.LuceneAccessorSupp
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.Spy
|
||||
* @see org.mockito.runners.MockitoJUnitRunner
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.springframework.data.gemfire.search.lucene.LuceneAccessor
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,7 @@ import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
@@ -62,7 +62,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.Spy
|
||||
* @see org.mockito.runners.MockitoJUnitRunner
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@@ -95,7 +95,6 @@ public class LuceneIndexFactoryBeanUnitTests {
|
||||
@Before
|
||||
public void setup() {
|
||||
factoryBean = spy(new LuceneIndexFactoryBean());
|
||||
doReturn(mockLuceneService).when(factoryBean).resolveLuceneService(eq(mockCache));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -86,7 +86,6 @@ public class ProjectingLuceneTemplateUnitTests {
|
||||
LuceneResultStruct<K, V> mockLuceneResultStruct =
|
||||
mock(LuceneResultStruct.class, String.format("MockLuceneResultStruct%s", key));
|
||||
|
||||
when(mockLuceneResultStruct.getKey()).thenReturn(key);
|
||||
when(mockLuceneResultStruct.getValue()).thenReturn(value);
|
||||
|
||||
return mockLuceneResultStruct;
|
||||
|
||||
@@ -75,9 +75,9 @@ public class LucenePageUnitTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> LuceneResultStruct<K, V> mockLuceneResultStruct(K key, V value) {
|
||||
LuceneResultStruct<K, V> mockLuceneResultStruct = mock(LuceneResultStruct.class);
|
||||
LuceneResultStruct<K, V> mockLuceneResultStruct = mock(LuceneResultStruct.class,
|
||||
String.format("MockLuceneResultStruct$%1$s", key));
|
||||
|
||||
when(mockLuceneResultStruct.getKey()).thenReturn(key);
|
||||
when(mockLuceneResultStruct.getValue()).thenReturn(value);
|
||||
|
||||
return mockLuceneResultStruct;
|
||||
|
||||
Reference in New Issue
Block a user