Adding xml parsing and generation logic We now have an xsd for the lucene elements, and a LuceneXmlParser service. Geode already has a mechanism to plug in additional xml parsers like LuceneXmlParsers by using the java service loader, which I have done.
I've written a LuceneIndexCreation object to match other configuration objects that get generated when a cache is parsed. This creation is attached to regions on index creation time so that when xml is generated, the creation object and generate the appropriate xml snippet. Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/5011ee51 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/5011ee51 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/5011ee51 Branch: refs/heads/develop Commit: 5011ee516d86c7dd116aa8707f561898e3a63541 Parents: d88ef88 Author: Dan Smith <[email protected]> Authored: Wed Oct 7 13:44:10 2015 -0700 Committer: Dan Smith <[email protected]> Committed: Thu Oct 8 10:26:08 2015 -0700 ---------------------------------------------------------------------- .../LuceneIndexForPartitionedRegion.java | 21 +----- .../cache/lucene/internal/LuceneIndexImpl.java | 16 +++- .../lucene/internal/LuceneServiceImpl.java | 8 +- .../internal/xml/LuceneIndexCreation.java | 76 +++++++++++++++++++ .../internal/xml/LuceneIndexXmlGenerator.java | 41 ++++++++++ .../internal/xml/LuceneServiceXmlGenerator.java | 20 +++++ .../lucene/internal/xml/LuceneXmlConstants.java | 12 +++ .../lucene/internal/xml/LuceneXmlParser.java | 54 ++++++++++++++ .../lucene/lucene-1.0.xsd | 36 +++++++++ ...ne.gemfire.internal.cache.xmlcache.XmlParser | 1 + ...neIndexXmlGeneratorIntegrationJUnitTest.java | 59 +++++++++++++++ .../xml/LuceneIndexXmlGeneratorJUnitTest.java | 44 +++++++++++ ...uceneIndexXmlParserIntegrationJUnitTest.java | 78 ++++++++++++++++++++ .../xml/LuceneIndexXmlParserJUnitTest.java | 41 ++++++++++ ...erIntegrationJUnitTest.createIndex.cache.xml | 16 ++++ ...serIntegrationJUnitTest.parseIndex.cache.xml | 16 ++++ 16 files changed, 514 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexForPartitionedRegion.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexForPartitionedRegion.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexForPartitionedRegion.java index f9e2c1d..2bf848f 100644 --- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexForPartitionedRegion.java +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexForPartitionedRegion.java @@ -1,37 +1,17 @@ package com.gemstone.gemfire.cache.lucene.internal; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.lucene.analysis.Analyzer; - import com.gemstone.gemfire.cache.Cache; -import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.PartitionAttributesFactory; -import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.RegionAttributes; -import com.gemstone.gemfire.cache.RegionFactory; import com.gemstone.gemfire.cache.RegionShortcut; import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue; -import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory; import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueFactoryImpl; import com.gemstone.gemfire.cache.asyncqueue.internal.AsyncEventQueueImpl; -import com.gemstone.gemfire.cache.execute.RegionFunctionContext; -import com.gemstone.gemfire.cache.lucene.LuceneIndex; import com.gemstone.gemfire.cache.lucene.internal.filesystem.ChunkKey; import com.gemstone.gemfire.cache.lucene.internal.filesystem.File; -import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository; import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.HeterogenousLuceneSerializer; -import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer; -import com.gemstone.gemfire.cache.partition.PartitionRegionHelper; -import com.gemstone.gemfire.internal.cache.InternalRegionArguments; import com.gemstone.gemfire.internal.cache.PartitionedRegion; -import com.gemstone.gemfire.internal.cache.RegionFactoryImpl; -import com.gemstone.gemfire.internal.i18n.LocalizedStrings; /* wrapper of IndexWriter */ public class LuceneIndexForPartitionedRegion extends LuceneIndexImpl { @@ -125,6 +105,7 @@ public class LuceneIndexForPartitionedRegion extends LuceneIndexImpl { logger.info("The AEQ "+aeq+" is created at another member"); } + addExtension(dataRegion); hasInitialized = true; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java index c2d2ce2..3964053 100644 --- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneIndexImpl.java @@ -11,6 +11,8 @@ import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.lucene.internal.filesystem.ChunkKey; import com.gemstone.gemfire.cache.lucene.internal.filesystem.File; import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager; +import com.gemstone.gemfire.cache.lucene.internal.xml.LuceneIndexCreation; +import com.gemstone.gemfire.internal.cache.PartitionedRegion; import com.gemstone.gemfire.internal.logging.LogService; public abstract class LuceneIndexImpl implements InternalLuceneIndex { @@ -74,6 +76,18 @@ public abstract class LuceneIndexImpl implements InternalLuceneIndex { return this.analyzer; } - protected void initialize() { + protected abstract void initialize(); + + /** + * Register an extension with the region + * so that xml will be generated for this index. + */ + protected void addExtension(PartitionedRegion dataRegion) { + LuceneIndexCreation creation = new LuceneIndexCreation(); + creation.setName(this.getName()); + creation.setFieldNames(this.getFieldNames()); + creation.setRegion(dataRegion); + creation.setFieldFieldAnalyzerMap(this.getFieldAnalyzerMap()); + dataRegion.getExtensionPoint().addExtension(creation, creation); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java index 2c4db9d..776d005 100644 --- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java @@ -22,6 +22,7 @@ import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesCollecto import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesCollectorManager; import com.gemstone.gemfire.cache.lucene.internal.filesystem.ChunkKey; import com.gemstone.gemfire.cache.lucene.internal.filesystem.File; +import com.gemstone.gemfire.cache.lucene.internal.xml.LuceneServiceXmlGenerator; import com.gemstone.gemfire.internal.DSFIDFactory; import com.gemstone.gemfire.internal.DataSerializableFixedID; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; @@ -147,14 +148,13 @@ public class LuceneServiceImpl implements InternalLuceneService { @Override public XmlGenerator<Cache> getXmlGenerator() { - // TODO Auto-generated method stub - return null; + return new LuceneServiceXmlGenerator(); } @Override public void onCreate(Extensible<Cache> source, Extensible<Cache> target) { - // TODO Auto-generated method stub - + //This is called when CacheCreation (source) is turned into a GemfireCacheImpl (target) + //nothing to do there. } public void registerIndex(LuceneIndex index){ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java new file mode 100644 index 0000000..abb147a --- /dev/null +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java @@ -0,0 +1,76 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import java.util.Map; + +import org.apache.lucene.analysis.Analyzer; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.cache.lucene.LuceneService; +import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider; +import com.gemstone.gemfire.internal.cache.extension.Extensible; +import com.gemstone.gemfire.internal.cache.extension.Extension; +import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator; + +public class LuceneIndexCreation implements LuceneIndex, Extension<Region<?, ?>> { + private Region region; + private String name; + private String[] fieldNames; + private Map<String, Analyzer> fieldFieldAnalyzerMap; + + + public void setRegion(Region region) { + this.region = region; + } + + public void setName(String name) { + this.name = name; + } + + public void setFieldNames(String[] fieldNames) { + this.fieldNames = fieldNames; + } + + public Map<String, Analyzer> getFieldFieldAnalyzerMap() { + return fieldFieldAnalyzerMap; + } + + public void setFieldFieldAnalyzerMap( + Map<String, Analyzer> fieldFieldAnalyzerMap) { + this.fieldFieldAnalyzerMap = fieldFieldAnalyzerMap; + } + + @Override + public Map<String, Analyzer> getFieldAnalyzerMap() { + return this.fieldFieldAnalyzerMap; + } + + public String getName() { + return name; + } + + public String[] getFieldNames() { + return fieldNames; + } + + @Override + public String getRegionPath() { + return region.getFullPath(); + } + + @Override + public XmlGenerator<Region<?, ?>> getXmlGenerator() { + return new LuceneIndexXmlGenerator(this); + } + + @Override + public void onCreate(Extensible<Region<?, ?>> source, + Extensible<Region<?, ?>> target) { + target.getExtensionPoint().addExtension(LuceneIndex.class, this); + Cache cache = target.getExtensionPoint().getTarget().getCache(); + LuceneService service = LuceneServiceProvider.get(cache); + //TODO - should this be a different method than the public API here? + service.createIndex(getName(), getRegionPath(), getFieldNames()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java new file mode 100644 index 0000000..161e981 --- /dev/null +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java @@ -0,0 +1,41 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator; +import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator; +import com.gemstone.gemfire.internal.cache.xmlcache.XmlGeneratorUtils; + +public class LuceneIndexXmlGenerator implements XmlGenerator<Region<?, ?>> { + private final LuceneIndex index; + + public LuceneIndexXmlGenerator(LuceneIndex index) { + this.index = index; + } + + @Override + public String getNamspaceUri() { + return NAMESPACE; + } + + @Override + public void generate(CacheXmlGenerator cacheXmlGenerator) + throws SAXException { + final ContentHandler handler = cacheXmlGenerator.getContentHandler(); + + handler.startPrefixMapping(PREFIX, NAMESPACE); + + AttributesImpl attr = new AttributesImpl(); + //TODO - should the type be xs:string ? + XmlGeneratorUtils.addAttribute(attr, NAME, index.getName()); + XmlGeneratorUtils.addAttribute(attr, FIELDS, String.join(",", index.getFieldNames())); + XmlGeneratorUtils.emptyElement(cacheXmlGenerator.getContentHandler(), PREFIX, INDEX, attr); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java new file mode 100644 index 0000000..6c0da01 --- /dev/null +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java @@ -0,0 +1,20 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import org.xml.sax.SAXException; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator; +import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator; + +public final class LuceneServiceXmlGenerator implements XmlGenerator<Cache> { + @Override + public String getNamspaceUri() { + return LuceneXmlConstants.NAMESPACE; + } + + @Override + public void generate(CacheXmlGenerator cacheXmlGenerator) + throws SAXException { + //Nothing to to the xml at the service level at the moment. + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java new file mode 100644 index 0000000..97193b8 --- /dev/null +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java @@ -0,0 +1,12 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +public class LuceneXmlConstants { + public static final String NAMESPACE= "http://geode.incubator.apache.org/schema/lucene"; + public static final String PREFIX = "lucene"; + public static final String SERVICE = "service"; + public static final String NAME = "name"; + public static final String REGION = "index"; + public static final String INDEX = "index"; + public static final String FIELDS = "fields"; + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java new file mode 100644 index 0000000..8630a44 --- /dev/null +++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java @@ -0,0 +1,54 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl; +import com.gemstone.gemfire.internal.cache.xmlcache.AbstractXmlParser; +import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation; +import com.gemstone.gemfire.internal.cache.xmlcache.RegionCreation; + +public class LuceneXmlParser extends AbstractXmlParser { + + @Override + public String getNamspaceUri() { + return NAMESPACE; + } + + @Override + public void startElement(String uri, String localName, String qName, + Attributes atts) throws SAXException { + + if(!NAMESPACE.equals(uri)) { + return; + } + if(INDEX.equals(localName)) { + startIndex(atts); + } + } + + private void startIndex(Attributes atts) { + final RegionCreation region = (RegionCreation) stack.peek(); + RegionAttributesCreation rac = (RegionAttributesCreation) region.getAttributes(); + String name = atts.getValue(NAME); + String[] fields = atts.getValue(FIELDS).split(" *, *"); + rac.addAsyncEventQueueId(LuceneServiceImpl.getUniqueIndexName(name, region.getFullPath())); + + + LuceneIndexCreation indexCreation = new LuceneIndexCreation(); + indexCreation.setName(name); + indexCreation.setFieldNames(fields); + indexCreation.setRegion(region); + region.getExtensionPoint().addExtension(indexCreation, indexCreation); + //TODO support nested field objects by adding the creation object to the stack + //stack.push(indexCreation) + } + + @Override + public void endElement(String uri, String localName, String qName) + throws SAXException { + //Nothing to do. + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/resources/META-INF/schemas/geode.incubator.apache.org/lucene/lucene-1.0.xsd ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/resources/META-INF/schemas/geode.incubator.apache.org/lucene/lucene-1.0.xsd b/gemfire-lucene/src/main/resources/META-INF/schemas/geode.incubator.apache.org/lucene/lucene-1.0.xsd new file mode 100644 index 0000000..66a4aad --- /dev/null +++ b/gemfire-lucene/src/main/resources/META-INF/schemas/geode.incubator.apache.org/lucene/lucene-1.0.xsd @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsd:schema + targetNamespace="http://geode.incubator.apache.org/schema/lucene" + xmlns:gpdb="http://geode.incubator.apache.org/schema/lucene" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" + attributeFormDefault="unqualified" + version="1.0"> + + <xsd:import + namespace="http://schema.pivotal.io/gemfire/cache" + schemaLocation="http://schema.pivotal.io/gemfire/cache/cache-9.0.xsd"/> + + <xsd:annotation> + <xsd:documentation><![CDATA[ +XML schema for Lucene indexes in Geode. + + <cache + xmlns="http://schema.pivotal.io/gemfire/cache" + xmlns:lucene="http://geode.incubator.apache.org/schema/lucene" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache + http://schema.pivotal.io/gemfire/cache/cache-9.0.xsd + http://geode.incubator.apache.org/schema/lucene + http://geode.incubator.apache.org/schema/lucene/lucene-1.0.xsd" + version="9.0"> + + ]]></xsd:documentation> + </xsd:annotation> + <xsd:element name="index"> + <xsd:complexType> + <xsd:attribute name="name" type="xsd:string"/> + <xsd:attribute name="fields" type="xsd:string"/> + </xsd:complexType> + </xsd:element> +</xsd:schema> http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.xmlcache.XmlParser ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.xmlcache.XmlParser b/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.xmlcache.XmlParser new file mode 100644 index 0000000..fc3abc0 --- /dev/null +++ b/gemfire-lucene/src/main/resources/META-INF/services/com.gemstone.gemfire.internal.cache.xmlcache.XmlParser @@ -0,0 +1 @@ +com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlParser \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorIntegrationJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorIntegrationJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorIntegrationJUnitTest.java new file mode 100644 index 0000000..65c73f7 --- /dev/null +++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorIntegrationJUnitTest.java @@ -0,0 +1,59 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static org.junit.Assert.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.nio.charset.Charset; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.RegionShortcut; +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.cache.lucene.LuceneService; +import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +@Category(IntegrationTest.class) +public class LuceneIndexXmlGeneratorIntegrationJUnitTest { + + /** + * Test of generating and reading cache configuration back in. + */ + @Test + public void generateWithFields() { + Cache cache = new CacheFactory().set("mcast-port", "0").create(); + cache.createRegionFactory(RegionShortcut.PARTITION).create("region"); + LuceneService service = LuceneServiceProvider.get(cache); + + service.createIndex("index", "region", "a", "b", "c"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(baos); + CacheXmlGenerator.generate(cache, pw, true, false, false); + pw.flush(); + + cache.close(); + cache = new CacheFactory().set("mcast-port", "0").create(); + + byte[] bytes = baos.toByteArray(); + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + System.out.println("---FILE---"); + System.out.println(new String(bytes, Charset.defaultCharset())); + cache.loadCacheXml(new ByteArrayInputStream(bytes)); + + LuceneService service2 = LuceneServiceProvider.get(cache); + assertTrue(service != service2); + + LuceneIndex index = service2.getIndex("index", "region"); + assertNotNull(index); + + assertArrayEquals(new String[] {"a", "b", "c"}, index.getFieldNames()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorJUnitTest.java new file mode 100644 index 0000000..a31e7e1 --- /dev/null +++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGeneratorJUnitTest.java @@ -0,0 +1,44 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class LuceneIndexXmlGeneratorJUnitTest { + + /** + * Test of generating and reading cache configuration back in. + * @throws SAXException + */ + @Test + public void generateWithFields() throws SAXException { + LuceneIndex index = Mockito.mock(LuceneIndex.class); + Mockito.when(index.getName()).thenReturn("index"); + Mockito.when(index.getFieldNames()).thenReturn(new String[] {"a", "b"}); + + LuceneIndexXmlGenerator generator = new LuceneIndexXmlGenerator(index); + CacheXmlGenerator cacheXmlGenerator = Mockito.mock(CacheXmlGenerator.class); + ContentHandler handler = Mockito.mock(ContentHandler.class); + Mockito.when(cacheXmlGenerator.getContentHandler()).thenReturn(handler); + generator.generate(cacheXmlGenerator); + + ArgumentCaptor<Attributes> captor = new ArgumentCaptor<>(); + Mockito.verify(handler).startElement(eq(""), eq("index"), eq("lucene:index"), captor.capture()); + Attributes value = captor.getValue(); + assertEquals("index", value.getValue(LuceneXmlConstants.NAME)); + assertEquals("a,b", value.getValue(LuceneXmlConstants.FIELDS)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.java new file mode 100644 index 0000000..56a726f --- /dev/null +++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.java @@ -0,0 +1,78 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static org.junit.Assert.*; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.cache.lucene.LuceneService; +import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider; +import com.gemstone.gemfire.internal.cache.extension.Extension; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation; +import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlParser; +import com.gemstone.gemfire.internal.cache.xmlcache.RegionCreation; +import com.gemstone.gemfire.test.junit.categories.UnitTest; +import com.gemstone.gemfire.util.test.TestUtil; + +@Category(UnitTest.class) +public class LuceneIndexXmlParserIntegrationJUnitTest { + + @Rule + public TestName name = new TestName(); + + /** + * Test that we parse the index fields correctly + */ + @Test + public void parseIndex() throws FileNotFoundException { + CacheXmlParser parser = CacheXmlParser.parse(new FileInputStream(getXmlFileForTest())); + CacheCreation cache = parser.getCacheCreation(); + RegionCreation region = (RegionCreation) cache.getRegion("region"); + Map<String, String[]> expectedIndexes = new HashMap<String, String[]>(); + expectedIndexes.put("index1", new String[] {"a", "b", "c", "d"}); + expectedIndexes.put("index2", new String[] { "f", "g"}); + for(Extension extension : region.getExtensionPoint().getExtensions()) { + LuceneIndexCreation index = (LuceneIndexCreation) extension; + assertEquals("/region", index.getRegionPath()); + assertArrayEquals(expectedIndexes.remove(index.getName()), index.getFieldNames()); + } + + assertEquals(Collections.emptyMap(),expectedIndexes); + } + + /** + * Test that the Index creation objects get appropriately translated + * into a real index. + * @throws FileNotFoundException + */ + @Test + public void createIndex() throws FileNotFoundException { + CacheFactory cf = new CacheFactory(); + cf.set("mcast-port", "0"); + cf.set("cache-xml-file", getXmlFileForTest()); + Cache cache = cf.create(); + + LuceneService service = LuceneServiceProvider.get(cache); + assertEquals(2, service.getAllIndexes().size()); + LuceneIndex index1 = service.getIndex("index1", "/region"); + LuceneIndex index2 = service.getIndex("index2", "/region"); + assertArrayEquals(index1.getFieldNames(), new String[] {"a", "b", "c", "d"}); + assertArrayEquals(index2.getFieldNames(), new String[] { "f", "g"}); + } + + private String getXmlFileForTest() { + return TestUtil.getResourcePath(getClass(), getClass().getSimpleName() + "." + name.getMethodName() + ".cache.xml"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserJUnitTest.java new file mode 100644 index 0000000..808c11e --- /dev/null +++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserJUnitTest.java @@ -0,0 +1,41 @@ +package com.gemstone.gemfire.cache.lucene.internal.xml; + +import static org.junit.Assert.*; + +import java.util.Stack; + +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation; +import com.gemstone.gemfire.internal.cache.xmlcache.RegionCreation; +import com.gemstone.gemfire.internal.cache.xmlcache.XmlGeneratorUtils; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class LuceneIndexXmlParserJUnitTest { + + @Test + public void generateWithFields() throws SAXException { + LuceneXmlParser parser = new LuceneXmlParser(); + AttributesImpl attrs = new AttributesImpl(); + CacheCreation cache = new CacheCreation(); + RegionCreation rc = new RegionCreation(cache, "region"); + Stack<Object> stack = new Stack<Object>(); + stack.push(cache); + stack.push(rc); + parser.setStack(stack); + XmlGeneratorUtils.addAttribute(attrs, LuceneXmlConstants.NAME, "index"); + XmlGeneratorUtils.addAttribute(attrs, LuceneXmlConstants.FIELDS, "a,b,c"); + parser.startElement(LuceneXmlConstants.NAMESPACE, LuceneXmlConstants.INDEX, null, attrs); + parser.endElement(LuceneXmlConstants.NAMESPACE, LuceneXmlConstants.INDEX, null); + + LuceneIndexCreation index = (LuceneIndexCreation) rc.getExtensionPoint().getExtensions().iterator().next(); + assertEquals("index", index.getName()); + assertArrayEquals(new String[] {"a", "b", "c"}, index.getFieldNames()); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.createIndex.cache.xml ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.createIndex.cache.xml b/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.createIndex.cache.xml new file mode 100644 index 0000000..8350650 --- /dev/null +++ b/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.createIndex.cache.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cache + xmlns="http://schema.pivotal.io/gemfire/cache" + xmlns:lucene="http://geode.incubator.apache.org/schema/lucene" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache + http://schema.pivotal.io/gemfire/cache/cache-9.0.xsd + http://geode.incubator.apache.org/schema/lucene + http://geode.incubator.apache.org/schema/lucene/lucene-1.0.xsd" + version="9.0"> + + <region name="region" refid="PARTITION"> + <lucene:index name="index1" fields="a, b,c,d"/> + <lucene:index name="index2" fields="f,g"/> + </region> +</cache> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5011ee51/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.parseIndex.cache.xml ---------------------------------------------------------------------- diff --git a/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.parseIndex.cache.xml b/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.parseIndex.cache.xml new file mode 100644 index 0000000..8350650 --- /dev/null +++ b/gemfire-lucene/src/test/resources/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlParserIntegrationJUnitTest.parseIndex.cache.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cache + xmlns="http://schema.pivotal.io/gemfire/cache" + xmlns:lucene="http://geode.incubator.apache.org/schema/lucene" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache + http://schema.pivotal.io/gemfire/cache/cache-9.0.xsd + http://geode.incubator.apache.org/schema/lucene + http://geode.incubator.apache.org/schema/lucene/lucene-1.0.xsd" + version="9.0"> + + <region name="region" refid="PARTITION"> + <lucene:index name="index1" fields="a, b,c,d"/> + <lucene:index name="index2" fields="f,g"/> + </region> +</cache> \ No newline at end of file
