View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.solr.index.handlers.content;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.logging.log4j.LogManager;
28  import org.apache.logging.log4j.Logger;
29  import org.apache.solr.client.solrj.SolrClient;
30  import org.apache.solr.client.solrj.SolrServerException;
31  import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
32  import org.apache.solr.client.solrj.impl.HttpSolrClient;
33  import org.apache.solr.client.solrj.response.UpdateResponse;
34  import org.apache.solr.common.SolrInputDocument;
35  import org.mycore.common.content.MCRContent;
36  import org.mycore.datamodel.metadata.MCRObjectID;
37  import org.mycore.solr.MCRSolrClientFactory;
38  import org.mycore.solr.index.MCRSolrIndexHandler;
39  import org.mycore.solr.index.document.MCRSolrInputDocumentFactory;
40  import org.mycore.solr.index.handlers.MCRSolrAbstractIndexHandler;
41  import org.mycore.solr.index.handlers.document.MCRSolrInputDocumentHandler;
42  import org.mycore.solr.index.statistic.MCRSolrIndexStatistic;
43  import org.mycore.solr.index.statistic.MCRSolrIndexStatisticCollector;
44  
45  /**
46   * @author Thomas Scheffler (yagee)
47   *
48   */
49  public class MCRSolrMCRContentMapIndexHandler extends MCRSolrAbstractIndexHandler {
50  
51      private static final Logger LOGGER = LogManager.getLogger(MCRSolrMCRContentMapIndexHandler.class);
52  
53      private List<MCRSolrIndexHandler> subhandlers;
54  
55      private Map<MCRObjectID, MCRContent> contentMap;
56  
57      public MCRSolrMCRContentMapIndexHandler(Map<MCRObjectID, MCRContent> contentMap) {
58          this(contentMap, MCRSolrClientFactory.getMainSolrClient());
59      }
60  
61      public MCRSolrMCRContentMapIndexHandler(Map<MCRObjectID, MCRContent> contentMap, SolrClient solrClient) {
62          super();
63          this.contentMap = contentMap;
64          this.subhandlers = new ArrayList<>(contentMap.size());
65      }
66  
67      @Override
68      public MCRSolrIndexStatistic getStatistic() {
69          return MCRSolrIndexStatisticCollector.DOCUMENTS;
70      }
71  
72      @Override
73      public void index() throws IOException, SolrServerException {
74          int totalCount = contentMap.size();
75          LOGGER.info("Handling {} documents", totalCount);
76          //multithread processing will result in too many http request
77          UpdateResponse updateResponse;
78          try {
79              Iterator<SolrInputDocument> documents = MCRSolrInputDocumentFactory.getInstance().getDocuments(contentMap);
80              SolrClient solrClient = getSolrClient();
81              if (solrClient instanceof ConcurrentUpdateSolrClient) {
82                  //split up to speed up processing
83                  splitup(documents);
84                  return;
85              }
86              if (LOGGER.isDebugEnabled()) {
87                  ArrayList<SolrInputDocument> debugList = new ArrayList<>();
88                  while (documents.hasNext()) {
89                      debugList.add(documents.next());
90                  }
91                  LOGGER.debug("Sending these documents: {}", debugList);
92                  //recreate documents interator;
93                  documents = debugList.iterator();
94              }
95              if (solrClient instanceof HttpSolrClient) {
96                  updateResponse = solrClient.add(documents);
97              } else {
98                  ArrayList<SolrInputDocument> docs = new ArrayList<>(totalCount);
99                  while (documents.hasNext()) {
100                     docs.add(documents.next());
101                 }
102                 updateResponse = solrClient.add(docs);
103             }
104         } catch (Throwable e) {
105             LOGGER.warn("Error while indexing document collection. Split and retry.", e);
106             splitup();
107             return;
108         }
109         if (updateResponse.getStatus() != 0) {
110             LOGGER.error("Error while indexing document collection. Split and retry: {}", updateResponse.getResponse());
111             splitup();
112         } else {
113             LOGGER.info("Sending {} documents was successful in {} ms.", totalCount, updateResponse.getElapsedTime());
114         }
115 
116     }
117 
118     private void splitup(Iterator<SolrInputDocument> documents) {
119         while (documents.hasNext()) {
120             MCRSolrInputDocumentHandler subhandler = new MCRSolrInputDocumentHandler(documents.next());
121             subhandler.setCommitWithin(getCommitWithin());
122             subhandlers.add(subhandler);
123         }
124         contentMap.clear();
125     }
126 
127     private void splitup() {
128         for (Map.Entry<MCRObjectID, MCRContent> entry : contentMap.entrySet()) {
129             MCRSolrMCRContentIndexHandler subHandler = new MCRSolrMCRContentIndexHandler(entry.getKey(),
130                 entry.getValue(), getSolrClient());
131             subHandler.setCommitWithin(getCommitWithin());
132             subhandlers.add(subHandler);
133         }
134         contentMap.clear();
135     }
136 
137     @Override
138     public List<MCRSolrIndexHandler> getSubHandlers() {
139         return subhandlers;
140     }
141 
142     @Override
143     public int getDocuments() {
144         return contentMap.size();
145     }
146 
147     @Override
148     public String toString() {
149         return "bulk index " + contentMap.size() + " documents";
150     }
151 
152 }