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 7460F200B92 for ; Wed, 14 Sep 2016 00:44:07 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 732FF160AD3; Tue, 13 Sep 2016 22:44:07 +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 C640A160AD8 for ; Wed, 14 Sep 2016 00:44:04 +0200 (CEST) Received: (qmail 29316 invoked by uid 500); 13 Sep 2016 22:44:03 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 29307 invoked by uid 99); 13 Sep 2016 22:44:03 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Sep 2016 22:44:03 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 3310E1A92B0 for ; Tue, 13 Sep 2016 22:44:03 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx2-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id yeBpFMe_e0LD for ; Tue, 13 Sep 2016 22:43:53 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-us.apache.org (ASF Mail Server at mx2-lw-us.apache.org) with SMTP id D88195FC37 for ; Tue, 13 Sep 2016 22:43:51 +0000 (UTC) Received: (qmail 28387 invoked by uid 99); 13 Sep 2016 22:43:51 -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; Tue, 13 Sep 2016 22:43:51 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4DA92E08B5; Tue, 13 Sep 2016 22:43:51 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: hiteshkhamesra@apache.org To: commits@geode.incubator.apache.org Date: Tue, 13 Sep 2016 22:44:36 -0000 Message-Id: <586ac3358a4445a984a0dd4f4d162c38@git.apache.org> In-Reply-To: <69ace8383aae47d1b0c2dc7793e01b2a@git.apache.org> References: <69ace8383aae47d1b0c2dc7793e01b2a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [48/61] [abbrv] incubator-geode git commit: GEODE-37 change package name from com.gemstone.gemfire (for ./geode-lucene/src/main/java/com/gemstone/gemfire)to org.apache.geode for(to ./geode-lucene/src/main/java/org/apache/geode) archived-at: Tue, 13 Sep 2016 22:44:07 -0000 http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java deleted file mode 100644 index e06f99e..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.repository.serializer; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.apache.logging.log4j.Logger; -import org.apache.lucene.document.Document; - -import com.gemstone.gemfire.internal.logging.LogService; - -/** - * A lucene serializer that handles a single class and can - * map an instance of that class to a document using reflection. - */ -class ReflectionLuceneSerializer implements LuceneSerializer { - - private Field[] fields; - - private static final Logger logger = LogService.getLogger(); - - public ReflectionLuceneSerializer(Class clazz, - String[] indexedFields) { - Set fieldSet = new HashSet(); - fieldSet.addAll(Arrays.asList(indexedFields)); - - //Iterate through all declared fields and save them - //in a list if they are an indexed field and have the correct - //type. - ArrayList foundFields = new ArrayList(); - while(clazz != Object.class) { - for(Field field : clazz.getDeclaredFields()) { - Class type = field.getType(); - if(fieldSet.contains(field.getName()) - && SerializerUtil.isSupported(type)) { - field.setAccessible(true); - foundFields.add(field); - } - } - - clazz = clazz.getSuperclass(); - } - - this.fields = foundFields.toArray(new Field[foundFields.size()]); - } - - @Override - public void toDocument(Object value, Document doc) { - for(Field field: fields) { - try { - Object fieldValue = field.get(value); - if (fieldValue == null) { - continue; - } - SerializerUtil.addField(doc, field.getName(), fieldValue); - } catch (IllegalArgumentException | IllegalAccessException e) { - //TODO - what to do if we can't read a field? - } - } - if (logger.isDebugEnabled()) { - logger.debug("ReflectionLuceneSerializer.toDocument:"+doc); - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java deleted file mode 100644 index 4d563c1..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.repository.serializer; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.DoublePoint; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.FloatPoint; -import org.apache.lucene.document.IntPoint; -import org.apache.lucene.document.LongPoint; -import org.apache.lucene.document.StringField; -import org.apache.lucene.document.TextField; -import org.apache.lucene.index.IndexableField; -import org.apache.lucene.index.Term; -import org.apache.lucene.util.BytesRef; - -import com.gemstone.gemfire.DataSerializer; -import com.gemstone.gemfire.InternalGemFireError; -import com.gemstone.gemfire.internal.util.BlobHelper; - -/** - * Static utility functions for mapping objects to lucene documents - */ -public class SerializerUtil { - private static final String KEY_FIELD = "_KEY"; - - private static final Set SUPPORTED_PRIMITIVE_TYPES; - - static { - HashSet primitiveTypes = new HashSet<>(); - primitiveTypes.add(String.class); - primitiveTypes.add(long.class); - primitiveTypes.add(int.class); - primitiveTypes.add(float.class); - primitiveTypes.add(double.class); - primitiveTypes.add(Long.class); - primitiveTypes.add(Integer.class); - primitiveTypes.add(Float.class); - primitiveTypes.add(Double.class); - - SUPPORTED_PRIMITIVE_TYPES = Collections.unmodifiableSet(primitiveTypes); - } - - /** - * A small buffer for converting keys to byte[] arrays. - */ - private static ThreadLocal LOCAL_BUFFER = new ThreadLocal() { - @Override - protected ByteArrayOutputStream initialValue() { - return new ByteArrayOutputStream(); - } - }; - - private SerializerUtil() { - } - - /** - * Add a gemfire key to a document - */ - public static void addKey(Object key, Document doc) { - if(key instanceof String) { - doc.add(new StringField(KEY_FIELD, (String) key, Store.YES)); - } else { - doc.add(new StringField(KEY_FIELD, keyToBytes(key), Store.YES)); - } - } - - /** - * Add a field to the document. - * - * @return true if the field was successfully added - */ - public static boolean addField(Document doc, String field, Object fieldValue) { - Class clazz = fieldValue.getClass(); - if(clazz == String.class) { - doc.add(new TextField(field, (String)fieldValue, Store.NO)); - } else if (clazz == Long.class) { - doc.add(new LongPoint(field, (Long) fieldValue)); - } else if (clazz == Integer.class) { - doc.add(new IntPoint(field, (Integer) fieldValue)); - } else if (clazz == Float.class) { - doc.add(new FloatPoint(field, (Float) fieldValue)); - } else if (clazz == Double.class) { - doc.add(new DoublePoint(field, (Double) fieldValue)); - } else { - return false; - } - - return true; - } - - /** - * Return true if a field type can be written to a lucene document. - */ - public static boolean isSupported(Class type) { - return SUPPORTED_PRIMITIVE_TYPES.contains(type); - } - - public static Collection supportedPrimitiveTypes() { - return SUPPORTED_PRIMITIVE_TYPES; - } - - /** - * Extract the gemfire key from a lucene document - */ - public static Object getKey(Document doc) { - IndexableField field = doc.getField(KEY_FIELD); - if(field.stringValue() != null) { - return field.stringValue(); - } else { - return keyFromBytes(field.binaryValue()); - } - } - - /** - * Extract the gemfire key term from a lucene document - */ - public static Term getKeyTerm(Document doc) { - IndexableField field = doc.getField(KEY_FIELD); - if(field.stringValue() != null) { - return new Term(KEY_FIELD, field.stringValue()); - } else { - return new Term(KEY_FIELD, field.binaryValue()); - } - } - - /** - * Convert a gemfire key into a key search term that can be used to - * update or delete the document associated with this key. - */ - public static Term toKeyTerm(Object key) { - if(key instanceof String) { - return new Term(KEY_FIELD, (String) key); - } else { - return new Term(KEY_FIELD, keyToBytes(key)); - } - } - - private static Object keyFromBytes(BytesRef bytes) { - try { - return BlobHelper.deserializeBlob(bytes.bytes); - } catch (ClassNotFoundException | IOException e) { - throw new InternalGemFireError(e); - } - } - - /** - * Convert a key to a byte array. - */ - private static BytesRef keyToBytes(Object key) { - ByteArrayOutputStream buffer = LOCAL_BUFFER.get(); - - try { - DataOutputStream out = new DataOutputStream(buffer); - DataSerializer.writeObject(key, out); - out.flush(); - BytesRef result = new BytesRef(buffer.toByteArray()); - buffer.reset(); - return result; - } catch (IOException e) { - throw new InternalGemFireError("Unable to serialize key", e); - } - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java deleted file mode 100644 index dca7737..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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. - */ -/** - * Classes for converting gemfire objects into lucene documents. - */ - -package com.gemstone.gemfire.cache.lucene.internal.repository.serializer; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java deleted file mode 100644 index 98233b0..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.xml; - -import java.util.*; - -import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper; -import org.apache.lucene.analysis.standard.StandardAnalyzer; - -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.cache.lucene.internal.LuceneServiceImpl; -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> { - private Region region; - private String name; - private Set fieldNames = new LinkedHashSet(); - private Map fieldAnalyzers; - - - public void setRegion(Region region) { - this.region = region; - } - - public void setName(String name) { - this.name = name; - } - - public void setFieldAnalyzers( - Map fieldAnalyzers) { - this.fieldAnalyzers = fieldAnalyzers; - } - - @Override - public Map getFieldAnalyzers() { - if (this.fieldAnalyzers == null) { - this.fieldAnalyzers = new HashMap<>(); - } - return this.fieldAnalyzers; - } - - public String getName() { - return name; - } - - public String[] getFieldNames() { - return fieldNames.toArray(new String[fieldNames.size()]); - } - - @Override - public String getRegionPath() { - return region.getFullPath(); - } - - @Override - public XmlGenerator> getXmlGenerator() { - return new LuceneIndexXmlGenerator(this); - } - - @Override - public void beforeCreate(Extensible> source, Cache cache) { - LuceneServiceImpl service = (LuceneServiceImpl) LuceneServiceProvider.get(cache); - Analyzer analyzer = this.fieldAnalyzers == null - ? new StandardAnalyzer() - : new PerFieldAnalyzerWrapper(new StandardAnalyzer(), this.fieldAnalyzers); - service.createIndex(getName(), getRegionPath(), analyzer, this.fieldAnalyzers, getFieldNames()); - } - - @Override - public void onCreate(Extensible> source, Extensible> target) {} - - protected void addField(String name) { - this.fieldNames.add(name); - } - - protected void addFieldAndAnalyzer(String name, Analyzer analyzer) { - this.fieldNames.add(name); - getFieldAnalyzers().put(name, analyzer); - } - - public void addFieldNames(String[] fieldNames) { - this.fieldNames.addAll(Arrays.asList(fieldNames)); - } - - @Override - public boolean waitUntilFlushed(int maxWaitInMillisecond) { - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java deleted file mode 100644 index 37c9ca2..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.xml; - -import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*; - -import org.apache.lucene.analysis.Analyzer; -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> { - 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.startElement(handler, PREFIX, INDEX, attr); - for(String field : index.getFieldNames()) { - AttributesImpl fieldAttr = new AttributesImpl(); - XmlGeneratorUtils.addAttribute(fieldAttr, NAME, field); - Analyzer analyzer = index.getFieldAnalyzers().get(field); - if (analyzer != null) { - XmlGeneratorUtils.addAttribute(fieldAttr, ANALYZER, analyzer.getClass().getName()); - } - XmlGeneratorUtils.emptyElement(handler, PREFIX, FIELD, fieldAttr); - } - XmlGeneratorUtils.endElement(handler, PREFIX, INDEX); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java deleted file mode 100644 index c449f47..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 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 { - @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/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java deleted file mode 100644 index 91d1643..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.xml; - -public class LuceneXmlConstants { - public static final String NAMESPACE= "http://geode.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 FIELD = "field"; - public static final String ANALYZER = "analyzer"; - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java deleted file mode 100644 index 5bdbe04..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 com.gemstone.gemfire.cache.lucene.internal.xml; - -import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*; - -import com.gemstone.gemfire.cache.CacheXmlException; -import com.gemstone.gemfire.internal.InternalDataSerializer; -import com.gemstone.gemfire.internal.i18n.LocalizedStrings; -import org.apache.lucene.analysis.Analyzer; -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); - } - if(FIELD.equals(localName)) { - startField(atts); - } - } - - private void startField(Attributes atts) { - //Ignore any whitespace noise between fields - if(stack.peek() instanceof StringBuffer) { - stack.pop(); - } - LuceneIndexCreation creation = (LuceneIndexCreation) stack.peek(); - String name = atts.getValue(NAME); - String className = atts.getValue(ANALYZER); - if (className == null) { - creation.addField(name); - } else { - Analyzer analyzer = createAnalyzer(className); - creation.addFieldAndAnalyzer(name, analyzer); - } - } - - private void startIndex(Attributes atts) { - final RegionCreation region = (RegionCreation) stack.peek(); - String name = atts.getValue(NAME); - LuceneIndexCreation indexCreation = new LuceneIndexCreation(); - indexCreation.setName(name); - indexCreation.setRegion(region); - region.getExtensionPoint().addExtension(indexCreation); - stack.push(indexCreation); - } - - @Override - public void endElement(String uri, String localName, String qName) - throws SAXException { - if(!NAMESPACE.equals(uri)) { - return; - } - if(INDEX.equals(localName)) { - endIndex(); - } - } - - private void endIndex() { - //Ignore any whitespace noise between fields - if(stack.peek() instanceof StringBuffer) { - stack.pop(); - } - - //Remove the index creation from the stack - stack.pop(); - } - - private Analyzer createAnalyzer(String className) { - Object obj; - try { - Class c = InternalDataSerializer.getCachedClass(className); - obj = c.newInstance(); - } - catch (Exception ex) { - throw new CacheXmlException(LocalizedStrings.CacheXmlParser_WHILE_INSTANTIATING_A_0.toLocalizedString(className), ex); - } - if (!(obj instanceof Analyzer)) { - throw new CacheXmlException(LocalizedStrings.LuceneXmlParser_CLASS_0_IS_NOT_AN_INSTANCE_OF_ANALYZER.toLocalizedString(className)); - } - return (Analyzer) obj; - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java deleted file mode 100644 index 4eb1ca3..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ -/** - * Classes for parsing lucene index elements a cache.xml file. See the lucene-1.0.xsd file for - * the schema. - */ - -package com.gemstone.gemfire.cache.lucene.internal.xml; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java deleted file mode 100644 index 0e0c89b..0000000 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ -/** - * This package provides an integration with Apache Lucene that allows Geode regions to be indexed in a distributed - * Lucene index and queries using Lucene queries. - *

- * All indexing and query operations are performed through the {@link com.gemstone.gemfire.cache.lucene.LuceneService} class. - * See {@link com.gemstone.gemfire.cache.lucene.LuceneService} for an example of how to add a lucene index to a geode region. - *

- * - * The Lucene indexes created using this API are stored in geode and colocated with the indexed region, which means they - * have the same availability guarantees as the underlying region. The indexes are maintained asynchronously, so changes - * to the region may not be immediately visible in the lucene index. - */ - -package com.gemstone.gemfire.cache.lucene; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java new file mode 100644 index 0000000..6b1a4b4 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java @@ -0,0 +1,66 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import java.util.Map; + +import org.apache.lucene.analysis.Analyzer; + +import com.gemstone.gemfire.annotations.Experimental; + + +/** + * An lucene index is built over the data stored in a GemFire Region. + *

+ * An index is specified using a index name, field names, region name. + *

+ * The index name and region name together uniquely identifies the lucene index. + *

+ * + */ +@Experimental +public interface LuceneIndex { + + /** + * @return the index name of this index + */ + public String getName(); + + /** + * @return the region name for this index + */ + public String getRegionPath(); + + /** + * @return the indexed field names in a Set + */ + public String[] getFieldNames(); + + /** + * @return the field to analyzer map + */ + public Map getFieldAnalyzers(); + + /* + * wait until the current entries in cache are indexed + * @param maxWaitInMilliseconds max wait time in millisecond + * @return if entries are flushed within maxWait + */ + public boolean waitUntilFlushed(int maxWaitInMillisecond); + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java new file mode 100644 index 0000000..7cc0977 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java @@ -0,0 +1,66 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import java.util.Collection; +import java.util.List; + +import com.gemstone.gemfire.annotations.Experimental; + +/** + * Provides wrapper object of Lucene's Query object and execute the search. + *

Instances of this interface are created using + * {@link LuceneQueryFactory#create}. + * + */ +@Experimental +public interface LuceneQuery { + /** + * Execute search and return keys. + */ + public Collection findKeys() throws LuceneQueryException; + + /** + * Execute search and return values. + */ + public Collection findValues() throws LuceneQueryException; + + /** + * Execute search and return list of LuceneResultStruct. + */ + public List> findResults() throws LuceneQueryException; + /** + * Execute the search and get results. + */ + public PageableLuceneQueryResults findPages() throws LuceneQueryException; + + /** + * Get page size setting of current query. + */ + public int getPageSize(); + + /** + * Get limit size setting of current query. + */ + public int getLimit(); + + /** + * Get projected fields setting of current query. + */ + public String[] getProjectedFieldNames(); + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java new file mode 100644 index 0000000..fb03b4a --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.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 com.gemstone.gemfire.cache.lucene; + +import com.gemstone.gemfire.GemFireCheckedException; + +/** + * Thrown when a lucene query fails. + */ +public class LuceneQueryException extends GemFireCheckedException { + + public LuceneQueryException(final String message) { + super(message); + } + + public LuceneQueryException(final String message, final Throwable cause) { + super(message, cause); + } + + public LuceneQueryException(final Throwable cause) { + super(cause); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java new file mode 100644 index 0000000..8e36bbb --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java @@ -0,0 +1,98 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import org.apache.lucene.queryparser.classic.ParseException; + +import com.gemstone.gemfire.annotations.Experimental; + +/** + * Factory for creating instances of {@link LuceneQuery}. + * To get an instance of this factory call {@link LuceneService#createLuceneQueryFactory}. + *

+ * To use this factory configure it with the set methods and then + * call {@link #create} to produce a {@link LuceneQuery} instance. + * + */ +@Experimental +public interface LuceneQueryFactory { + + /** + * Default query result limit is 100 + */ + public static final int DEFAULT_LIMIT = 100; + + /** + * Default page size of result is 0, which means no pagination + */ + public static final int DEFAULT_PAGESIZE = 0; + + /** + * Set page size for a query result. The default page size is 0 which means no pagination. + * If specified negative value, throw IllegalArgumentException + * @param pageSize + * @return itself + */ + LuceneQueryFactory setPageSize(int pageSize); + + /** + * Set max limit of result for a query + * If specified limit is less or equal to zero, throw IllegalArgumentException + * @param limit + * @return itself + */ + LuceneQueryFactory setResultLimit(int limit); + + /** + * Set a list of fields for result projection. + * + * @param fieldNames + * @return itself + * + * @deprecated TODO This feature is not yet implemented + */ + @Deprecated + LuceneQueryFactory setProjectionFields(String... fieldNames); + + /** + * Create wrapper object for lucene's QueryParser object using default standard analyzer. + * The queryString is using lucene QueryParser's syntax. QueryParser is for easy-to-use + * with human understandable syntax. + * + * @param regionName region name + * @param indexName index name + * @param queryString query string in lucene QueryParser's syntax + * @param defaultField default field used by the Lucene Query Parser + * @param the key type in the query results + * @param the value type in the query results + * @return LuceneQuery object + */ + public LuceneQuery create(String indexName, String regionName, String queryString, String defaultField); + + /** + * Creates a wrapper object for Lucene's Query object. This {@link LuceneQuery} builder method could be used in + * advanced cases, such as cases where Lucene's Query object construction needs Lucene's API over query string. + * + * @param indexName index name + * @param regionName region name + * @param provider constructs and provides a Lucene Query object + * @param the key type in the query results + * @param the value type in the query results + * @return LuceneQuery object + */ + public LuceneQuery create(String indexName, String regionName, LuceneQueryProvider provider); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java new file mode 100644 index 0000000..7f1c269 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java @@ -0,0 +1,47 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import java.io.Serializable; + +import org.apache.lucene.search.Query; + +import com.gemstone.gemfire.annotations.Experimental; +import com.gemstone.gemfire.cache.query.QueryException; + +/** + * The instances of this class will be used for distributing Lucene Query objects and re-constructing the Query object. + * If necessary the implementation needs to take care of serializing and de-serializing Lucene Query object. Geode + * respects the DataSerializable contract to provide optimal object serialization. For instance, + * {@link LuceneQueryProvider}'s toData method will be used to serialize it when it is sent to another member of the + * distributed system. Implementation of DataSerializable can provide a zero-argument constructor that will be invoked + * when they are read with DataSerializer.readObject. + */ +@Experimental +public interface LuceneQueryProvider extends Serializable { + /** + * @return A Lucene Query object which could be used for executing Lucene Search on indexed data + * @param index local lucene index the query is being constructed against. + * @throws LuceneQueryException if the provider fails to construct the query object + */ + + public Query getQuery(LuceneIndex index) throws LuceneQueryException; + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java new file mode 100644 index 0000000..bc587f5 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java @@ -0,0 +1,61 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import com.gemstone.gemfire.annotations.Experimental; + +/** + *

+ * Abstract data structure for one item in query result. + * + */ +@Experimental +public interface LuceneResultStruct { + /** + * Return the value associated with the given field name + * + * @param fieldName the String name of the field + * @return the value associated with the specified field + * @throws IllegalArgumentException If this struct does not have a field named fieldName + */ + public Object getProjectedField(String fieldName); + + /** + * Return key of the entry + * + * @return key + * @throws IllegalArgumentException If this struct does not contain key + */ + public K getKey(); + + /** + * Return value of the entry + * + * @return value the whole domain object + * @throws IllegalArgumentException If this struct does not contain value + */ + public V getValue(); + + /** + * Return score of the query + * + * @return score + * @throws IllegalArgumentException If this struct does not contain score + */ + public float getScore(); +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java new file mode 100644 index 0000000..cf1f735 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java @@ -0,0 +1,129 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import java.util.Collection; +import java.util.Map; + +import org.apache.lucene.analysis.Analyzer; + +import com.gemstone.gemfire.annotations.Experimental; +import com.gemstone.gemfire.cache.GemFireCache; +import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexCreationProfile; + +/** + * LuceneService instance is a singleton for each cache. + * + * It provides handle for managing the {@link LuceneIndex} and create the {@link LuceneQuery} + * via {@link LuceneQueryFactory} + * + *

+ * Example:
+ * + *
+ * At client and server JVM, initializing cache will create the LuceneServiceImpl object, 
+ * which is a singleton at each JVM. 
+ * 
+ * At each server JVM, for data region to create index, create the index on fields with default analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, "field1", "field2", "field3"); 
+ * or create index on fields with specified analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, analyzerPerField);
+ * 
+ * We can also create index via cache.xml or gfsh.
+ * 
+ * At client side, create query and run the search:
+ * 
+ * LuceneQuery query = luceneService.createLuceneQueryFactory().setLimit(200).setPageSize(20)
+ * .setResultTypes(SCORE, VALUE, KEY).setFieldProjection("field1", "field2")
+ * .create(indexName, regionName, querystring, analyzer);
+ * 
+ * The querystring is using lucene's queryparser syntax, such as "field1:zhou* AND field2:gzhou@pivotal.io"
+ *  
+ * PageableLuceneQueryResults results = query.search();
+ * 
+ * If pagination is not specified:
+ * List list = results.getNextPage(); // return all results in one getNextPage() call
+ * or if paging is specified:
+ * if (results.hasNextPage()) {
+ *   List page = results.nextPage(); // return resules page by page
+ * }
+ * 
+ * The item of the list is either the domain object or instance of {@link LuceneResultStruct}
+ * 
+ * + * + */ +@Experimental +public interface LuceneService { + + /** + * A special field name that indicates that the entire region value should + * be indexed. This will only work if the region value is a String or Number, in + * which case a lucene document will be created with a single field with this name. + */ + String REGION_VALUE_FIELD = "__REGION_VALUE_FIELD"; + + /** + * Create a lucene index using default analyzer. + * @param fields The fields of the object to index. Only fields listed here will be stored + * in the index. Fields should map to PDX fieldNames if the object is serialized with PDX, or + * to java fields on the object otherwise. The special field name {{@link #REGION_VALUE_FIELD}} + * indicates that the entire value should be stored as a single field in the index. + */ + public void createIndex(String indexName, String regionPath, String... fields); + + /** + * Create a lucene index using specified analyzer per field + * + * @param indexName index name + * @param regionPath region name + * @param analyzerPerField A map of fields to analyzers. See {{@link #createIndex(String, String, String...)}} + * for details on valid values for fields. Each field will be tokenized using the provided Analyzer. + */ + public void createIndex(String indexName, String regionPath, + Map analyzerPerField); + + /** + * Destroy the lucene index + * + * @param index index object + * @deprecated TODO This feature is not yet implemented + */ + @Deprecated + public void destroyIndex(LuceneIndex index); + + /** + * Get the lucene index object specified by region name and index name + * @param indexName index name + * @param regionPath region name + * @return LuceneIndex object + */ + public LuceneIndex getIndex(String indexName, String regionPath); + + /** + * get all the lucene indexes. + * @return all index objects in a Collection + */ + public Collection getAllIndexes(); + + /** + * create LuceneQueryFactory + * @return LuceneQueryFactory object + */ + public LuceneQueryFactory createLuceneQueryFactory(); + + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java new file mode 100644 index 0000000..f83dffa --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java @@ -0,0 +1,45 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import com.gemstone.gemfire.annotations.Experimental; +import com.gemstone.gemfire.cache.GemFireCache; +import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneService; +import com.gemstone.gemfire.internal.cache.InternalCache; + +/** + * Class for retrieving or creating the currently running + * instance of the LuceneService. + * + */ +@Experimental +public class LuceneServiceProvider { + /** + * Retrieve or create the lucene service for this cache + */ + public static LuceneService get(GemFireCache cache) { + InternalCache internalCache = (InternalCache) cache; + return internalCache.getService(InternalLuceneService.class); + } + + private LuceneServiceProvider() { + + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java new file mode 100644 index 0000000..c2def44 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java @@ -0,0 +1,58 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene; + +import java.util.Iterator; +import java.util.List; + +import com.gemstone.gemfire.annotations.Experimental; + +/** + *

+ * Defines the interface for a container of lucene query result collected from function execution.
+ * + * + * @param The type of the key + * @param The type of the value + */ +@Experimental +public interface PageableLuceneQueryResults extends Iterator>> { + /** + * @return total number of hits for this query + */ + public int size(); + + /** + * Returns the maximum score value encountered. Note that in case scores are not tracked, this returns {@link Float#NaN}. + */ + public float getMaxScore(); + + /** + * Get the next page of results. + * + * @return a page of results, or null if there are no more pages + */ + public List> next(); + + /** + * True if there another page of results. + */ + public boolean hasNext(); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java new file mode 100755 index 0000000..1dc716c --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java @@ -0,0 +1,124 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import com.gemstone.gemfire.InternalGemFireError; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.execute.RegionFunctionContext; +import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository; +import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager; +import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer; +import com.gemstone.gemfire.internal.cache.BucketNotFoundException; +import com.gemstone.gemfire.internal.cache.BucketRegion; +import com.gemstone.gemfire.internal.cache.PartitionedRegion; +import com.gemstone.gemfire.internal.cache.execute.InternalRegionFunctionContext; + +public abstract class AbstractPartitionedRepositoryManager implements RepositoryManager { + + /** map of the parent bucket region to the index repository + * + * This is based on the BucketRegion in case a bucket is rebalanced, we don't want to + * return a stale index repository. If a bucket moves off of this node and + * comes back, it will have a new BucketRegion object. + * + * It is weak so that the old BucketRegion will be garbage collected. + */ + protected final ConcurrentHashMap indexRepositories = new ConcurrentHashMap(); + + /** The user region for this index */ + protected final PartitionedRegion userRegion; + protected final LuceneSerializer serializer; + protected final LuceneIndexImpl index; + + public AbstractPartitionedRepositoryManager( + LuceneIndexImpl index, + LuceneSerializer serializer) { + this.index = index; + this.userRegion = (PartitionedRegion)index.getCache().getRegion(index.getRegionPath()); + this.serializer = serializer; + } + + @Override + public IndexRepository getRepository(Region region, Object key, + Object callbackArg) throws BucketNotFoundException { + BucketRegion userBucket = userRegion.getBucketRegion(key, callbackArg); + if(userBucket == null) { + throw new BucketNotFoundException("User bucket was not found for region " + region + "key " + key + " callbackarg " + callbackArg); + } + + return getRepository(userBucket.getId()); + } + + @Override + public Collection getRepositories(RegionFunctionContext ctx) throws BucketNotFoundException { + Region region = ctx.getDataSet(); + Set buckets = ((InternalRegionFunctionContext) ctx).getLocalBucketSet(region); + ArrayList repos = new ArrayList(buckets.size()); + for(Integer bucketId : buckets) { + BucketRegion userBucket = userRegion.getDataStore().getLocalBucketById(bucketId); + if(userBucket == null) { + throw new BucketNotFoundException("User bucket was not found for region " + region + "bucket id " + bucketId); + } else { + repos.add(getRepository(userBucket.getId())); + } + } + + return repos; + } + + public abstract IndexRepository createOneIndexRepository(final Integer bucketId, + LuceneSerializer serializer, + LuceneIndexImpl index, PartitionedRegion userRegion) throws IOException; + + /** + * Return the repository for a given user bucket + */ + protected IndexRepository getRepository(Integer bucketId) throws BucketNotFoundException { + IndexRepository repo = indexRepositories.get(bucketId); + if(repo != null && !repo.isClosed()) { + return repo; + } + + repo = indexRepositories.compute(bucketId, (key, oldRepository) -> { + if(oldRepository != null && !oldRepository.isClosed()) { + return oldRepository; + } + if(oldRepository != null) { + oldRepository.cleanup(); + } + + try { + return createOneIndexRepository(bucketId, serializer, index, userRegion); + } catch(IOException e) { + throw new InternalGemFireError("Unable to create index repository", e); + } + + }); + + if(repo == null) { + throw new BucketNotFoundException("Colocated index buckets not found for bucket id " + bucketId); + } + + return repo; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java new file mode 100644 index 0000000..c9c03a5 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java @@ -0,0 +1,35 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import org.apache.lucene.analysis.Analyzer; + +import java.util.Map; + +public interface IndexListener { + + public void beforeIndexCreated(final String indexName, String regionPath, + final Analyzer analyzer, final Map fieldAnalyzers, + final String... fields); + + public void afterIndexCreated(LuceneIndex index); + + public void beforeIndexDestroyed(LuceneIndex index); + + public void afterIndexDestroyed(LuceneIndex index); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java new file mode 100644 index 0000000..dd916ac --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.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 com.gemstone.gemfire.cache.lucene.internal; + +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import org.apache.lucene.analysis.Analyzer; + +import java.util.Map; + +public class IndexListenerAdapter implements IndexListener { + @Override + public void beforeIndexCreated(String indexName, String regionPath, Analyzer analyzer, + Map fieldAnalyzers, String... fields) { + } + + @Override + public void afterIndexCreated(LuceneIndex index) { + } + + @Override + public void beforeIndexDestroyed(LuceneIndex index) { + } + + @Override + public void afterIndexDestroyed(LuceneIndex index) { + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java new file mode 100644 index 0000000..e6f01b0 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java @@ -0,0 +1,66 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import java.io.IOException; + +import com.gemstone.gemfire.cache.lucene.internal.directory.RegionDirectory; +import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository; +import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepositoryImpl; +import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer; +import com.gemstone.gemfire.internal.cache.BucketNotFoundException; +import com.gemstone.gemfire.internal.cache.BucketRegion; +import com.gemstone.gemfire.internal.cache.PartitionedRegion; + +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; + +public class IndexRepositoryFactory { + + public IndexRepositoryFactory() { + } + + public IndexRepository createIndexRepository(final Integer bucketId, + LuceneSerializer serializer, + LuceneIndexImpl index, PartitionedRegion userRegion) + throws IOException + { + final IndexRepository repo; + LuceneIndexForPartitionedRegion indexForPR = (LuceneIndexForPartitionedRegion)index; + BucketRegion fileBucket = getMatchingBucket(indexForPR.getFileRegion(), bucketId); + BucketRegion chunkBucket = getMatchingBucket(indexForPR.getChunkRegion(), bucketId); + BucketRegion dataBucket = getMatchingBucket(userRegion, bucketId); + if(fileBucket == null || chunkBucket == null) { + return null; + } + RegionDirectory dir = new RegionDirectory(fileBucket, chunkBucket, indexForPR.getFileSystemStats()); + IndexWriterConfig config = new IndexWriterConfig(indexForPR.getAnalyzer()); + IndexWriter writer = new IndexWriter(dir, config); + repo = new IndexRepositoryImpl(fileBucket, writer, serializer, indexForPR.getIndexStats(), dataBucket); + return repo; + } + + /** + * Find the bucket in region2 that matches the bucket id from region1. + */ + protected BucketRegion getMatchingBucket(PartitionedRegion region, Integer bucketId) { + //Force the bucket to be created if it is not already + region.getOrCreateNodeForBucketWrite(bucketId, null); + + return region.getDataStore().getLocalBucketById(bucketId); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java new file mode 100644 index 0000000..27b4820 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java @@ -0,0 +1,34 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager; + +public interface InternalLuceneIndex extends LuceneIndex { + + public RepositoryManager getRepositoryManager(); + + /** + * Dump the files for this index to the given directory. + */ + public void dumpFiles(String directory); + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java new file mode 100644 index 0000000..403853e --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java @@ -0,0 +1,29 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.lucene.LuceneService; +import com.gemstone.gemfire.internal.cache.CacheService; +import com.gemstone.gemfire.internal.cache.extension.Extension; + +public interface InternalLuceneService extends LuceneService, Extension, CacheService { + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java new file mode 100644 index 0000000..29fb159 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java @@ -0,0 +1,107 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.logging.log4j.Logger; + +import com.gemstone.gemfire.InternalGemFireError; +import com.gemstone.gemfire.cache.Operation; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionDestroyedException; +import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent; +import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener; +import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager; +import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository; +import com.gemstone.gemfire.cache.query.internal.DefaultQuery; +import com.gemstone.gemfire.internal.cache.BucketNotFoundException; +import com.gemstone.gemfire.internal.cache.CacheObserverHolder; +import com.gemstone.gemfire.internal.cache.PrimaryBucketException; +import com.gemstone.gemfire.internal.cache.partitioned.Bucket; +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.TestHook; +import com.gemstone.gemfire.internal.logging.LogService; + +/** + * An Async event queue listener that writes all of the + * events in batches to Lucene + */ +public class LuceneEventListener implements AsyncEventListener { + Logger logger = LogService.getLogger(); + + private final RepositoryManager repositoryManager; + + public LuceneEventListener(RepositoryManager repositoryManager) { + this.repositoryManager = repositoryManager; + } + + @Override + public void close() { + } + + @Override + public boolean processEvents(List events) { + // Try to get a PDX instance if possible, rather than a deserialized object + DefaultQuery.setPdxReadSerialized(true); + + Set affectedRepos = new HashSet(); + + try { + for (AsyncEvent event : events) { + Region region = event.getRegion(); + Object key = event.getKey(); + Object callbackArgument = event.getCallbackArgument(); + + IndexRepository repository = repositoryManager.getRepository(region, key, callbackArgument); + + Operation op = event.getOperation(); + + if (op.isCreate()) { + repository.update(key, event.getDeserializedValue()); + } else if (op.isUpdate()) { + repository.update(key, event.getDeserializedValue()); + } else if (op.isDestroy()) { + repository.delete(key); + } else if (op.isInvalidate()) { + repository.delete(key); + } else { + throw new InternalGemFireError("Unhandled operation " + op + " on " + event.getRegion()); + } + affectedRepos.add(repository); + } + + for(IndexRepository repo : affectedRepos) { + repo.commit(); + } + return true; + } catch(BucketNotFoundException | RegionDestroyedException | PrimaryBucketException e) { + logger.debug("Bucket not found while saving to lucene index: " + e.getMessage()); + return false; + } catch(IOException e) { + logger.error("Unable to save to lucene index", e); + return false; + } finally { + DefaultQuery.setPdxReadSerialized(false); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java new file mode 100644 index 0000000..de331ea --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java @@ -0,0 +1,172 @@ +/* + * 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 com.gemstone.gemfire.cache.lucene.internal; + +import com.gemstone.gemfire.DataSerializable; +import com.gemstone.gemfire.DataSerializer; +import com.gemstone.gemfire.internal.Version; +import com.gemstone.gemfire.internal.cache.CacheServiceProfile; +import com.gemstone.gemfire.internal.i18n.LocalizedStrings; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.*; + +public class LuceneIndexCreationProfile implements CacheServiceProfile, DataSerializable { + + private String indexName; + + private String[] fieldNames; + + private String analyzerClass; + + private Map fieldAnalyzers; + + private String regionPath; + + /* Used by DataSerializer */ + public LuceneIndexCreationProfile() {} + + public LuceneIndexCreationProfile(String indexName, String regionPath, String[] fieldNames, Analyzer analyzer, + Map fieldAnalyzers) { + this.indexName = indexName; + this.regionPath = regionPath; + this.fieldNames = fieldNames; + this.analyzerClass = analyzer.getClass().getSimpleName(); + initializeFieldAnalyzers(fieldAnalyzers); + } + + public String getIndexName() { + return this.indexName; + } + + public String[] getFieldNames() { + return this.fieldNames; + } + + public String getAnalyzerClass() { + return this.analyzerClass; + } + + public Map getFieldAnalyzers() { + return this.fieldAnalyzers; + } + + protected void initializeFieldAnalyzers(Map fieldAnalyzers) { + this.fieldAnalyzers = new HashMap<>(); + for (String field : fieldNames) { + if(fieldAnalyzers != null && !fieldAnalyzers.isEmpty()) { + this.fieldAnalyzers.put(field, fieldAnalyzers.get(field) == null ? StandardAnalyzer.class.getSimpleName() : fieldAnalyzers.get(field).getClass().getSimpleName()); + } else { + this.fieldAnalyzers.put(field, StandardAnalyzer.class.getSimpleName()); + } + } + } + + @Override + public String getId() { + return "lucene_"+LuceneServiceImpl.getUniqueIndexName(indexName, regionPath); + } + + @Override + public String checkCompatibility(String regionPath, CacheServiceProfile profile) { + String result = null; + LuceneIndexCreationProfile remoteProfile = (LuceneIndexCreationProfile) profile; + if (remoteProfile == null) { + // TODO This can occur if one member defines no indexes but another one does. Currently this is caught by the async event id checks. + } else { + // Verify fields are the same + if (!Arrays.equals(remoteProfile.getFieldNames(), getFieldNames())) { + return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3 + .toString(getIndexName(), regionPath, Arrays.toString(getFieldNames()), Arrays.toString(remoteProfile.getFieldNames())); + } + + // Verify the analyzer class is the same + // Note: This test will currently only fail if per-field analyzers are used in one member but not another, + // This condition will be caught in the tests below so this test is commented out. If we ever allow the user + // to configure a single analyzer for all fields, then this test will be useful again. + /* + if (!remoteLuceneIndexProfile.getAnalyzerClass().isInstance(getAnalyzer())) { + result = LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_3 + .toString(indexName, regionPath, remoteLuceneIndexProfile.getAnalyzerClass().getName(), analyzer.getClass().getName()); + } + */ + + // Iterate the existing analyzers and compare them to the input analyzers + // Note: This is currently destructive to the input field analyzers map which should be ok since its a transient object. + if (!getFieldAnalyzers().equals(remoteProfile.getFieldAnalyzers())) { + if (getFieldAnalyzers().size() != remoteProfile.getFieldAnalyzers().size()) { + return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3 + .toString(getIndexName(), regionPath, + Arrays.toString(getFieldAnalyzers().keySet().toArray()), + Arrays.toString(remoteProfile.getFieldAnalyzers().keySet().toArray())); + } + // now the 2 maps should have the same size + for (String field:getFieldAnalyzers().keySet()) { + if (!remoteProfile.getFieldAnalyzers().get(field).equals(getFieldAnalyzers().get(field))) { + return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_ON_FIELD_3_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_4_ON_THAT_FIELD + .toString(getIndexName(), regionPath, + getFieldAnalyzers().get(field), field, + remoteProfile.getFieldAnalyzers().get(field)); + } + } + } + } + return result; + } + + @Override + public void toData(DataOutput out) throws IOException { + DataSerializer.writeString(this.indexName, out); + DataSerializer.writeString(this.regionPath, out); + DataSerializer.writeStringArray(this.fieldNames, out); + DataSerializer.writeString(this.analyzerClass, out); + DataSerializer.writeHashMap(this.fieldAnalyzers, out); + } + + @Override + public void fromData(DataInput in) throws IOException, ClassNotFoundException { + this.indexName = DataSerializer.readString(in); + this.regionPath = DataSerializer.readString(in); + this.fieldNames = DataSerializer.readStringArray(in); + this.analyzerClass = DataSerializer.readString(in); + this.fieldAnalyzers = DataSerializer.readHashMap(in); + } + + public String toString() { + return new StringBuilder() + .append(getClass().getSimpleName()) + .append("[") + .append("indexName=") + .append(this.indexName) + .append("; fieldNames=") + .append(Arrays.toString(this.fieldNames)) + .append("; analyzerClass=") + .append(this.analyzerClass) + .append("; fieldAnalyzers=") + .append(this.fieldAnalyzers) + .append("]") + .toString(); + } + + public String getRegionPath() { + return this.regionPath; + } +}