package com.constellio.data.utils.scripts; import java.util.ArrayList; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; import com.constellio.data.utils.ThreadList; public class CopySolrIndexMain { public static void main(String argv[]) throws Exception { if (argv.length < 4) { System.out.println("Usage : CopySolrIndexMain <batch> <thread> <input-solr-server> <output-solr-server>"); System.out .println( "Exemple : CopySolrIndexMain 500 2 http://localhost:8983/solr/records http://localhost:8984/solr/records"); System.exit(0); } //SolrClient inputClient = new HttpSolrClient("http://localhost:8985/solr/records"); //SolrClient outputClient = new HttpSolrClient("http://localhost:8986/solr/records"); int batchSize = Integer.valueOf(argv[0]); int nbThreads = Integer.valueOf(argv[1]); SolrClient inputClient = new HttpSolrClient(argv[2]); SolrClient outputClient = new HttpSolrClient(argv[3]); inputClient.commit(); outputClient.commit(); LinkedBlockingQueue<ReindexSolrIndexesMainTask> queue = new LinkedBlockingQueue<>(nbThreads); startAddThreads(outputClient, queue, nbThreads); String lastId = null; if (argv.length == 3) { lastId = argv[2]; } int size = getSize(inputClient, lastId); int current = 0; List<SolrDocument> documents; while (!(documents = nextDocuments(inputClient, lastId, batchSize)).isEmpty()) { queue.put(new ReindexSolrIndexesMainTask(documents)); current += batchSize; String firstId = (String) documents.get(0).getFieldValue("id"); lastId = (String) documents.get(documents.size() - 1).getFieldValue("id"); System.out.println("Indexing " + current + "/" + size + " : " + firstId + "-" + lastId); } stopThreads(queue, nbThreads); outputClient.commit(); } private static int getSize(SolrClient client, String lastId) throws Exception { ModifiableSolrParams params = new ModifiableSolrParams(); if (lastId == null) { params.set("q", "*:*"); } else { params.set("q", "id:{" + lastId + " TO *}"); } params.set("rows", 0); return ((Long) client.query(params).getResults().getNumFound()).intValue(); } private static List<SolrInputDocument> toInputDocuments(List<SolrDocument> documents) { List<SolrInputDocument> inputDocuments = new ArrayList<>(); for (SolrDocument document : documents) { SolrInputDocument inputDocument = new SolrInputDocument(); for (String fieldName : document.getFieldNames()) { if (!fieldName.equals("_version_")) { Object value = document.get(fieldName); inputDocument.addField(fieldName, value); } } inputDocuments.add(inputDocument); } return inputDocuments; } private static List<SolrDocument> nextDocuments(SolrClient client, String lastId, int batchSize) throws Exception { ModifiableSolrParams params = new ModifiableSolrParams(); params.set("sort", "id asc"); if (lastId == null) { params.set("q", "*:*"); } else { params.set("q", "id:{" + lastId + " TO *}"); } params.set("rows", batchSize); List<SolrDocument> documents = client.query(params).getResults(); return documents; } private static void stopThreads(LinkedBlockingQueue<ReindexSolrIndexesMainTask> queue, int nbThreads) throws Exception { for (int i = 0; i < nbThreads; i++) { queue.put(new ReindexSolrIndexesMainTask(null)); } } private static void startAddThreads(final SolrClient client, final LinkedBlockingQueue<ReindexSolrIndexesMainTask> queue, int nbThreads) { ThreadList<Thread> threadList = new ThreadList<>(); for (int i = 0; i < nbThreads; i++) { final int threadId = i; threadList.addAndStart(new Thread() { @Override public void run() { while (true) { try { ReindexSolrIndexesMainTask nextTask = queue.take(); if (nextTask.documentList != null) { List<SolrInputDocument> documents = toInputDocuments(nextTask.documentList); client.add(documents); if (threadId == 0) { client.commit(true, true, true); } } else { break; } } catch (Exception e) { e.printStackTrace(); } } } }); } } private static class ReindexSolrIndexesMainTask { List<SolrDocument> documentList; public ReindexSolrIndexesMainTask(List<SolrDocument> documentList) { this.documentList = documentList; } } }