com.senseidb.search.node.inmemory.InMemorySenseiService.java Source code

Java tutorial

Introduction

Here is the source code for com.senseidb.search.node.inmemory.InMemorySenseiService.java

Source

/**
 * This software is licensed to you under the Apache License, Version 2.0 (the
 * "Apache License").
 *
 * LinkedIn's contributions are made under the Apache License. If you contribute
 * to the Software, the contributions will be deemed to have been made under the
 * Apache License, unless you expressly indicate otherwise. Please do not make any
 * contributions that would be inconsistent with the Apache License.
 *
 * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, this software
 * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache
 * License for the specific language governing permissions and limitations for the
 * software governed under the Apache License.
 *
 *  2012 LinkedIn Corp. All Rights Reserved.  
 */
package com.senseidb.search.node.inmemory;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.management.MBeanServer;

import com.browseengine.bobo.facets.filter.AdaptiveFacetFilter;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.json.JSONException;
import org.json.JSONObject;

import proj.zoie.api.ZoieIndexReader;
import proj.zoie.api.ZoieMultiReader;
import proj.zoie.api.ZoieSegmentReader;
import proj.zoie.api.indexing.AbstractZoieIndexable;
import proj.zoie.api.indexing.ZoieIndexable;
import proj.zoie.impl.indexing.ZoieConfig;

import com.browseengine.bobo.api.BoboIndexReader;
import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.facets.RuntimeFacetHandlerFactory;
import com.senseidb.conf.SenseiFacetHandlerBuilder;
import com.senseidb.conf.SenseiSchema;
import com.senseidb.conf.SenseiServerBuilder;
import com.senseidb.indexing.DefaultJsonSchemaInterpreter;
import com.senseidb.indexing.ShardingStrategy;
import com.senseidb.indexing.activity.ActivityPersistenceFactory;
import com.senseidb.jmx.JmxUtil;
import com.senseidb.jmx.MockJMXServer;
import com.senseidb.plugin.SenseiPluginRegistry;
import com.senseidb.search.node.SenseiIndexReaderDecorator;
import com.senseidb.search.plugin.PluggableSearchEngineManager;
import com.senseidb.search.req.SenseiRequest;
import com.senseidb.search.req.SenseiResult;
import com.senseidb.search.req.SenseiSystemInfo;
import com.senseidb.svc.impl.CoreSenseiServiceImpl;

public class InMemorySenseiService {
    private DefaultJsonSchemaInterpreter defaultJsonSchemaInterpreter;
    private List<FacetHandler<?>> facets;
    private List<RuntimeFacetHandlerFactory<?, ?>> runtimeFacets;

    private CoreSenseiServiceImpl coreSenseiServiceImpl;
    private PluggableSearchEngineManager pluggableSearchEngineManager;
    private MockSenseiCore mockSenseiCore;
    private SenseiSystemInfo senseiSystemInfo;
    private SenseiIndexReaderDecorator senseiIndexReaderDecorator;

    public InMemorySenseiService(SenseiSchema schema, SenseiPluginRegistry pluginRegistry) {
        MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
        schema.setCompressSrcData(false);
        try {
            platformMBeanServer = JmxUtil.registerNewJmxServer(new MockJMXServer());
            defaultJsonSchemaInterpreter = new DefaultJsonSchemaInterpreter(schema);
            facets = new ArrayList<FacetHandler<?>>();
            runtimeFacets = new ArrayList<RuntimeFacetHandlerFactory<?, ?>>();

            ShardingStrategy strategy = new ShardingStrategy() {
                public int caculateShard(int maxShardId, JSONObject dataObj) throws JSONException {
                    return 0;
                }
            };
            ActivityPersistenceFactory
                    .setOverrideForCurrentThread(ActivityPersistenceFactory.getInMemoryInstance());
            pluggableSearchEngineManager = new PluggableSearchEngineManager();
            pluggableSearchEngineManager.init("", 0, schema, ZoieConfig.DEFAULT_VERSION_COMPARATOR, pluginRegistry,
                    strategy);
            senseiSystemInfo = SenseiFacetHandlerBuilder.buildFacets(schema.getSchemaObj(), pluginRegistry, facets,
                    runtimeFacets, pluggableSearchEngineManager,
                    AdaptiveFacetFilter.DEFAULT_INVERTED_INDEX_PENALTY);

            int[] partitions = new int[] { 0 };
            senseiIndexReaderDecorator = new SenseiIndexReaderDecorator(facets, runtimeFacets);
            mockSenseiCore = new MockSenseiCore(partitions, senseiIndexReaderDecorator);
            pluggableSearchEngineManager.start(mockSenseiCore);
            coreSenseiServiceImpl = new CoreSenseiServiceImpl(mockSenseiCore);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JmxUtil.registerNewJmxServer(platformMBeanServer);
            ActivityPersistenceFactory.setOverrideForCurrentThread(null);

        }
    }

    private void addDocuments(Directory directory, IndexWriter writer, List<JSONObject> documents) {
        try {
            writer.deleteAll();
            for (JSONObject doc : documents) {
                if (doc == null)
                    continue;
                writer.addDocument(buildDoc(doc));
                pluggableSearchEngineManager.update(doc, "");
            }
            writer.commit();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public SenseiResult doQuery(SenseiRequest senseiRequest, List<JSONObject> documents) {
        Directory directory = null;
        IndexWriter writer = null;
        try {
            directory = new RAMDirectory();
            writer = new IndexWriter(directory,
                    new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
            addDocuments(directory, writer, documents);
            ZoieIndexReader<BoboIndexReader> zoieMultiReader = new ZoieMultiReader<BoboIndexReader>(
                    IndexReader.open(directory), new SenseiIndexReaderDecorator(facets, runtimeFacets));
            MockIndexReaderFactory mockIndexReaderFactory = new MockIndexReaderFactory<ZoieIndexReader<BoboIndexReader>>(
                    Arrays.asList(zoieMultiReader));
            mockSenseiCore.setIndexReaderFactory(mockIndexReaderFactory);
            SenseiResult result = coreSenseiServiceImpl.execute(senseiRequest);
            mockSenseiCore.setIndexReaderFactory(null);
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
                if (directory != null) {
                    directory.close();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    public Document buildDoc(JSONObject json) {
        ZoieIndexable indexable = defaultJsonSchemaInterpreter.convertAndInterpret(json);
        Document ret = indexable.buildIndexingReqs()[0].getDocument();
        ret.add(new Field(AbstractZoieIndexable.DOCUMENT_STORE_FIELD, indexable.getStoreValue()));
        ZoieSegmentReader.fillDocumentID(ret, indexable.getUID());
        return ret;
    }

    public static InMemorySenseiService valueOf(File confDir) {
        try {
            JSONObject schema = SenseiServerBuilder.loadSchema(confDir);
            File senseiConfFile = new File(confDir, SenseiServerBuilder.SENSEI_PROPERTIES);
            if (!senseiConfFile.exists()) {
                throw new ConfigurationException(
                        "configuration file: " + senseiConfFile.getAbsolutePath() + " does not exist.");
            }
            Configuration senseiConf = new PropertiesConfiguration();
            ((PropertiesConfiguration) senseiConf).setDelimiterParsingDisabled(true);
            ((PropertiesConfiguration) senseiConf).load(senseiConfFile);
            return new InMemorySenseiService(SenseiSchema.build(schema), SenseiPluginRegistry.build(senseiConf));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public SenseiSystemInfo getSenseiSystemInfo() {
        return senseiSystemInfo;
    }

    public void setSenseiSystemInfo(SenseiSystemInfo senseiSystemInfo) {
        this.senseiSystemInfo = senseiSystemInfo;
    }
}