Java tutorial
/** * Copyright 2012-2013 The MITRE Corporation. * * Licensed 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. * * * ************************************************************************** * NOTICE This software was produced for the U. S. Government under Contract No. * W15P7T-12-C-F600, and is subject to the Rights in Noncommercial Computer * Software and Noncommercial Computer Software Documentation Clause * 252.227-7014 (JUN 1995) * * (c) 2012 The MITRE Corporation. All Rights Reserved. * ************************************************************************** * */ package org.opensextant.util; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.CoreContainer; import org.opensextant.ConfigException; import org.opensextant.data.Place; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * As Xponents is a multi-core instance of Solr, a single default solr home and default solr core * does not make sense. Each wrapper around Solr (via SolrProxy) needs to name the solr home and an explicit core name. * * @author ubaldino */ public class SolrProxy extends SolrUtil { /**A single method to help find a suitable value for SOLR HOME * * If given is null, then system variables are checked. * @param given solr home. */ public static String deriveSolrHome(String given) throws ConfigException { if (given != null) { return given; } String solrHome = System.getProperty("opensextant.solr"); if (solrHome != null) { return solrHome; } solrHome = System.getProperty("solr.solr.home"); if (solrHome != null) { return solrHome; } solrHome = System.getProperty("solr.url"); if (solrHome != null) { return solrHome; } throw new ConfigException( "A non-null value for SOLR HOME is required; Either pass to constructor, set opensextant.solr, set solr.solr.home, or solr.url"); } protected String solrHome = null; protected String coreName = null; /** * Initializes a Solr server from a URL * * @throws IOException err */ public SolrProxy(URL url) throws IOException { this.server_url = url; solrServer = initializeHTTP(this.server_url); } /** * Initializes a Solr server from the SOLR_HOME environment variable. * * @param core name of solr core * @throws ConfigException cfg err */ public SolrProxy(String core) throws ConfigException { this.server_url = null; this.solrHome = deriveSolrHome(null); this.coreName = core; solrServer = setupCore(solrHome, core); } /** * Initializes a Solr server from the SOLR_HOME environment variable. * * @param solr_home the solr_home * @param core name of solr core * @throws ConfigException cfg err */ public SolrProxy(String solr_home, String core) throws ConfigException { this.server_url = null; solrHome = solr_home; this.coreName = core; solrServer = setupCore(solrHome, core); } protected Logger logger = LoggerFactory.getLogger(SolrProxy.class); protected SolrServer solrServer = null; private UpdateRequest solrUpdate = null; protected URL server_url = null; private boolean writable = false; public void setWritable(boolean b) { writable = b; } /** * * Is Solr server instance allowed to write to index? * @return true if index is intended to be writable. */ public boolean isWritable() { return writable; } /** * Get an HTTP server for Solr. * * @param url server represented by URL * @return Instance of a Solr server * @throws MalformedURLException */ public static SolrServer initializeHTTP(URL url) throws MalformedURLException { HttpSolrServer server = new HttpSolrServer(url.toString()); server.setAllowCompression(true); return server; } /** * Creates an EmbeddedSolrServer given solr home & the core to use. * These may be null and you get the default. * * @param _solrHome solr home * @param _coreName name of core * @return the embedded solr server * @throws ConfigException on err */ public static EmbeddedSolrServer setupCore(String _solrHome, String _coreName) throws ConfigException { try { CoreContainer solrContainer; if (_solrHome == null) { solrContainer = new CoreContainer(); } else { solrContainer = new CoreContainer(_solrHome); } solrContainer.load();// since Solr 4.4 return new EmbeddedSolrServer(solrContainer, _coreName); } catch (Exception err) { throw new ConfigException("Failed to set up Embedded Solr at " + _solrHome + " CORE:" + _coreName, err); } } /** * Creates the bare minimum Gazetteer Place record * @param gazEntry a solr document of key/value pairs * @return Place obj */ public static Place createPlace(SolrDocument gazEntry) { Place bean = new Place(SolrUtil.getString(gazEntry, "place_id"), SolrProxy.getString(gazEntry, "name")); populatePlace(gazEntry, bean); return bean; } /** * Populate the data card. * @param gazEntry solr doc * @param bean place obj to populate */ public static void populatePlace(SolrDocument gazEntry, Place bean) { String nt = SolrUtil.getString(gazEntry, "name_type"); if (nt != null) { if ("code".equals(nt)) { bean.setName_type('A'); } else { bean.setName_type(nt.charAt(0)); } } bean.setCountryCode(SolrUtil.getString(gazEntry, "cc")); // Other metadata. bean.setAdmin1(SolrUtil.getString(gazEntry, "adm1")); bean.setAdmin2(SolrUtil.getString(gazEntry, "adm2")); bean.setFeatureClass(SolrUtil.getString(gazEntry, "feat_class")); bean.setFeatureCode(SolrUtil.getString(gazEntry, "feat_code")); // Geo field is specifically Spatial4J lat,lon format. // Value should have already been validated as it was stored in index double[] xy = SolrUtil.getCoordinate(gazEntry, "geo"); bean.setLatitude(xy[0]); bean.setLongitude(xy[1]); bean.setName_bias(SolrUtil.getDouble(gazEntry, "name_bias")); bean.setId_bias(SolrUtil.getDouble(gazEntry, "id_bias")); } /** * Search an OpenSextant solr gazetteer. * * @param index solr server handle * @param qparams search parameters * @return list of places * @throws SolrServerException on err */ public static List<Place> searchGazetteer(SolrServer index, SolrParams qparams) throws SolrServerException { QueryResponse response = index.query(qparams, SolrRequest.METHOD.GET); List<Place> places = new ArrayList<>(); SolrDocumentList docList = response.getResults(); for (SolrDocument solrDoc : docList) { places.add(SolrProxy.createPlace(solrDoc)); } return places; } /** * Add one solr record. * * @param solrRecord document/gazetteer or other entry to add to index * @throws Exception on err ??? */ public void add(SolrInputDocument solrRecord) throws Exception { if (!this.writable) { throw new Exception("This instance is not configured for writing to index"); } // Initialize per batch if nec.y if (solrUpdate == null) { solrUpdate = new UpdateRequest(); } // Initialize per record // .. add data to record // .. add record to batch request solrUpdate.add(solrRecord); } /** * Add many solr records. * * @param solrRecords array of records to add * @throws Exception on err */ public void add(java.util.Collection<SolrInputDocument> solrRecords) throws Exception { if (!this.writable) { throw new Exception("This instance is not configured for writing to index"); } // Initialize per batch if nec.y if (solrUpdate == null) { solrUpdate = new UpdateRequest(); } // Initialize per record // .. add data to record // .. add record to batch request solrUpdate.add(solrRecords); } /** * Reopen an existing solr proxy. * * @throws ConfigException the config exception * @throws IOException Signals that an I/O exception has occurred. */ public void openIndex() throws ConfigException, IOException { if (solrServer == null) { if (server_url != null) { solrServer = initializeHTTP(server_url); } else { solrServer = setupCore(solrHome, coreName); } } } /** * Optimizes the Solr server. * * @throws IOException on err * @throws SolrServerException the solr server exception */ public void optimize() throws IOException, SolrServerException { solrServer.optimize(true, false); // Don't wait' } /** * Invokes <code>saveIndex(false)</code> */ public void saveIndex() { saveIndex(false); } /** * Save and optionally records to server or index On failure, current * accumulating request is cleared and nullified to avoid retransmitting bad * data. * * In the event of a failure all records since last "saveIndex" would be * lost and should be resubmitted. * * @param commit true, if we should commit updates */ public void saveIndex(boolean commit) { if (solrUpdate == null) { return; } logger.info("Saving records to index"); try { solrServer.request(solrUpdate); if (commit) { solrServer.commit(); } solrUpdate.clear(); solrUpdate = null; } catch (Exception filex) { logger.error("Index failed during indexing", filex); solrUpdate.clear(); solrUpdate = null; } } /** * Save and reopen. * * @throws ConfigException the config exception * @throws IOException on err */ public void saveAndReopen() throws ConfigException, IOException { saveIndex(/* commit = */true); openIndex(); } /** * */ public void close() { if (isWritable()) { saveIndex(); } if (solrServer != null) { solrServer.shutdown(); solrServer = null; } } public SolrServer getInternalSolrServer() { return solrServer; } }