/**
* ServerMirror
* Copyright 2013 by Michael Peter Christen
* First released 18.02.2013 at http://yacy.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program in the file lgpl21.txt
* If not, see <http://www.gnu.org/licenses/>.
*/
package net.yacy.cora.federate.solr.instance;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.StreamingResponseCallback;
import org.apache.solr.client.solrj.SolrRequest.METHOD;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SolrPingResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
public class ServerMirror extends SolrClient {
private static final long serialVersionUID = 4665364470785220322L;
private SolrClient solr0, solr1;
public ServerMirror() {
solr0 = null;
solr1 = null;
}
public void connect0(SolrClient solr0) {
this.solr0 = solr0;
}
public void connect1(SolrClient solr1) {
this.solr1 = solr1;
}
/**
* Adds a collection of documents
* @param docs the collection of documents
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse add(Collection<SolrInputDocument> docs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.add(docs);
if (this.solr1 != null) ur = this.solr1.add(docs);
return ur;
}
/**
* Adds a collection of documents, specifying max time before they become committed
* @param docs the collection of documents
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since solr 3.5
*/
@Override
public UpdateResponse add(Collection<SolrInputDocument> docs, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.add(docs, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.add(docs, commitWithinMs);
return ur;
}
/**
* Adds a collection of beans
* @param beans the collection of beans
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse addBeans(Collection<?> beans ) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.addBeans(beans);
if (this.solr1 != null) ur = this.solr1.addBeans(beans);
return ur;
}
/**
* Adds a collection of beans specifying max time before they become committed
* @param beans the collection of beans
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since solr 3.5
*/
@Override
public UpdateResponse addBeans(Collection<?> beans, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.addBeans(beans, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.addBeans(beans, commitWithinMs);
return ur;
}
/**
* Adds a single document
* @param doc the input document
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse add(SolrInputDocument doc) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.add(doc);
if (this.solr1 != null) ur = this.solr1.add(doc);
return ur;
}
/**
* Adds a single document specifying max time before it becomes committed
* @param doc the input document
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since solr 3.5
*/
@Override
public UpdateResponse add(SolrInputDocument doc, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.add(doc, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.add(doc, commitWithinMs);
return ur;
}
/**
* Adds a single bean
* @param obj the input bean
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse addBean(Object obj) throws IOException, SolrServerException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.addBean(obj);
if (this.solr1 != null) ur = this.solr1.addBean(obj);
return ur;
}
/**
* Adds a single bean specifying max time before it becomes committed
* @param obj the input bean
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since solr 3.5
*/
@Override
public UpdateResponse addBean(Object obj, int commitWithinMs) throws IOException, SolrServerException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.addBean(obj, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.addBean(obj, commitWithinMs);
return ur;
}
/**
* Performs an explicit commit, causing pending documents to be committed for indexing
* <p>
* waitFlush=true and waitSearcher=true to be inline with the defaults for plain HTTP access
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse commit() throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.commit();
if (this.solr1 != null) ur = this.solr1.commit();
return ur;
}
/**
* Performs an explicit optimize, causing a merge of all segments to one.
* <p>
* waitFlush=true and waitSearcher=true to be inline with the defaults for plain HTTP access
* <p>
* Note: In most cases it is not required to do explicit optimize
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse optimize() throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.optimize();
if (this.solr1 != null) ur = this.solr1.optimize();
return ur;
}
/**
* Performs an explicit commit, causing pending documents to be committed for indexing
* @param waitFlush block until index changes are flushed to disk
* @param waitSearcher block until a new searcher is opened and registered as the main query searcher, making the changes visible
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse commit(boolean waitFlush, boolean waitSearcher) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.commit(waitFlush, waitSearcher);
if (this.solr1 != null) ur = this.solr1.commit(waitFlush, waitSearcher);
return ur;
}
/**
* Performs an explicit commit, causing pending documents to be committed for indexing
* @param waitFlush block until index changes are flushed to disk
* @param waitSearcher block until a new searcher is opened and registered as the main query searcher, making the changes visible
* @param softCommit makes index changes visible while neither fsync-ing index files nor writing a new index descriptor
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse commit( boolean waitFlush, boolean waitSearcher, boolean softCommit ) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.commit(waitFlush, waitSearcher, softCommit);
if (this.solr1 != null) ur = this.solr1.commit(waitFlush, waitSearcher, softCommit);
return ur;
}
/**
* Performs an explicit optimize, causing a merge of all segments to one.
* <p>
* Note: In most cases it is not required to do explicit optimize
* @param waitFlush block until index changes are flushed to disk
* @param waitSearcher block until a new searcher is opened and registered as the main query searcher, making the changes visible
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse optimize(boolean waitFlush, boolean waitSearcher) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.optimize(waitFlush, waitSearcher);
if (this.solr1 != null) ur = this.solr1.optimize(waitFlush, waitSearcher);
return ur;
}
/**
* Performs an explicit optimize, causing a merge of all segments to one.
* <p>
* Note: In most cases it is not required to do explicit optimize
* @param waitFlush block until index changes are flushed to disk
* @param waitSearcher block until a new searcher is opened and registered as the main query searcher, making the changes visible
* @param maxSegments optimizes down to at most this number of segments
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse optimize(boolean waitFlush, boolean waitSearcher, int maxSegments ) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.optimize(waitFlush, waitSearcher, maxSegments);
if (this.solr1 != null) ur = this.solr1.optimize(waitFlush, waitSearcher, maxSegments);
return ur;
}
/**
* Performs a rollback of all non-committed documents pending.
* <p>
* Note that this is not a true rollback as in databases. Content you have previously
* added may have been committed due to autoCommit, buffer full, other client performing
* a commit etc.
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse rollback() throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.rollback();
if (this.solr1 != null) ur = this.solr1.rollback();
return ur;
}
/**
* Deletes a single document by unique ID
* @param id the ID of the document to delete
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse deleteById(String id) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteById(id);
if (this.solr1 != null) ur = this.solr1.deleteById(id);
return ur;
}
/**
* Deletes a single document by unique ID, specifying max time before commit
* @param id the ID of the document to delete
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since 3.6
*/
@Override
public UpdateResponse deleteById(String id, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteById(id, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.deleteById(id, commitWithinMs);
return ur;
}
/**
* Deletes a list of documents by unique ID
* @param ids the list of document IDs to delete
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse deleteById(List<String> ids) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteById(ids);
if (this.solr1 != null) ur = this.solr1.deleteById(ids);
return ur;
}
/**
* Deletes a list of documents by unique ID, specifying max time before commit
* @param ids the list of document IDs to delete
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since 3.6
*/
@Override
public UpdateResponse deleteById(List<String> ids, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteById(ids, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.deleteById(ids, commitWithinMs);
return ur;
}
/**
* Deletes documents from the index based on a query
* @param query the query expressing what documents to delete
* @throws IOException If there is a low-level I/O error.
*/
@Override
public UpdateResponse deleteByQuery(String query) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteByQuery(query);
if (this.solr1 != null) ur = this.solr1.deleteByQuery(query);
return ur;
}
/**
* Deletes documents from the index based on a query, specifying max time before commit
* @param query the query expressing what documents to delete
* @param commitWithinMs max time (in ms) before a commit will happen
* @throws IOException If there is a low-level I/O error.
* @since 3.6
*/
@Override
public UpdateResponse deleteByQuery(String query, int commitWithinMs) throws SolrServerException, IOException {
UpdateResponse ur = null;
if (this.solr0 != null) ur = this.solr0.deleteByQuery(query, commitWithinMs);
if (this.solr1 != null) ur = this.solr1.deleteByQuery(query, commitWithinMs);
return ur;
}
/**
* Issues a ping request to check if the server is alive
* @throws IOException If there is a low-level I/O error.
*/
@Override
public SolrPingResponse ping() throws SolrServerException, IOException {
if (this.solr0 != null) return this.solr0.ping();
if (this.solr1 != null) return this.solr1.ping();
return null;
}
/**
* Performs a query to the Solr server
* @param params an object holding all key/value parameters to send along the request
* @throws IOException
*/
@Override
public QueryResponse query(SolrParams params) throws SolrServerException, IOException {
if (this.solr0 != null) return this.solr0.query(params);
if (this.solr1 != null) return this.solr1.query(params);
return null;
}
/**
* Performs a query to the Solr server
* @param params an object holding all key/value parameters to send along the request
* @param method specifies the HTTP method to use for the request, such as GET or POST
* @throws IOException
*/
@Override
public QueryResponse query(SolrParams params, METHOD method) throws SolrServerException, IOException {
if (this.solr0 != null) return this.solr0.query(params, method);
if (this.solr1 != null) return this.solr1.query(params, method);
return null;
}
/**
* Query solr, and stream the results. Unlike the standard query, this will
* send events for each Document rather then add them to the QueryResponse.
*
* Although this function returns a 'QueryResponse' it should be used with care
* since it excludes anything that was passed to callback. Also note that
* future version may pass even more info to the callback and may not return
* the results in the QueryResponse.
*
* @since solr 4.0
*/
@Override
public QueryResponse queryAndStreamResponse( SolrParams params, StreamingResponseCallback callback ) throws SolrServerException, IOException {
if (this.solr0 != null) return this.solr0.queryAndStreamResponse(params, callback);
if (this.solr1 != null) return this.solr1.queryAndStreamResponse(params, callback);
return null;
}
/**
* SolrServer implementations need to implement how a request is actually processed
*/
@Override
public NamedList<Object> request(@SuppressWarnings("rawtypes") SolrRequest request, String collection) throws SolrServerException, IOException {
if (this.solr0 != null) return this.solr0.request(request, collection);
if (this.solr1 != null) return this.solr1.request(request, collection);
return null;
}
@Override
public DocumentObjectBinder getBinder() {
if (this.solr0 != null) return this.solr0.getBinder();
if (this.solr1 != null) return this.solr1.getBinder();
return null;
}
@Override
public void shutdown() {
if (this.solr0 != null)
try {
this.solr0.close();
} catch (IOException e) {
e.printStackTrace();
}
if (this.solr1 != null)
try {
this.solr1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}