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;
20  
21  import static org.mycore.solr.MCRSolrConstants.SOLR_CONFIG_PREFIX;
22  
23  import java.io.IOException;
24  
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.Logger;
27  import org.apache.solr.client.solrj.SolrClient;
28  import org.apache.solr.client.solrj.SolrServerException;
29  import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
30  import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
31  import org.apache.solr.client.solrj.impl.HttpSolrClient;
32  import org.mycore.common.config.MCRConfiguration2;
33  import org.mycore.common.events.MCRShutdownHandler;
34  
35  /**
36   * Core instance of a solr server.
37   * 
38   * @author Matthias Eichner
39   */
40  public class MCRSolrCore {
41  
42      private static final Logger LOGGER = LogManager.getLogger(MCRSolrCore.class);
43  
44      private static boolean USE_CONCURRENT_SERVER;
45  
46      protected String serverURL;
47  
48      protected String name;
49  
50      protected HttpSolrClient solrClient;
51  
52      protected ConcurrentUpdateSolrClient concurrentClient;
53  
54      static {
55          USE_CONCURRENT_SERVER = MCRConfiguration2
56              .getOrThrow(SOLR_CONFIG_PREFIX + "ConcurrentUpdateSolrClient.Enabled", Boolean::parseBoolean);
57      }
58  
59      /**
60       * Creates a new solr server core instance. The last part of this url should be the core.
61       *
62       * @param serverURL
63       *            whole url e.g. http://localhost:8296/docportal
64       * @deprecated use {@link #MCRSolrCore(String, String)} instead
65       */
66      @Deprecated
67      public MCRSolrCore(String serverURL) {
68          if (serverURL.endsWith("/")) {
69              serverURL = serverURL.substring(0, serverURL.length() - 1);
70          }
71          int i = serverURL.lastIndexOf("/") + 1;
72          setup(serverURL.substring(0, i), serverURL.substring(i));
73      }
74  
75      /**
76       * Creates a new solr server core instance.
77       * 
78       * @param serverURL
79       *            base url of the solr server e.g. http://localhost:8296
80       * @param name
81       *            name of the core e.g. docportal
82       */
83      public MCRSolrCore(String serverURL, String name) {
84          setup(serverURL, name);
85      }
86  
87      protected void setup(String serverURL, String name) {
88          if (!serverURL.endsWith("/")) {
89              serverURL += "/";
90          }
91          this.serverURL = serverURL;
92          this.name = name;
93          String coreURL = getV1CoreURL();
94          int connectionTimeout = MCRConfiguration2
95              .getOrThrow(SOLR_CONFIG_PREFIX + "SolrClient.ConnectionTimeout", Integer::parseInt);
96          int socketTimeout = MCRConfiguration2
97              .getOrThrow(SOLR_CONFIG_PREFIX + "SolrClient.SocketTimeout", Integer::parseInt);
98  
99          // default server
100         solrClient = new HttpSolrClient.Builder(coreURL)
101             .withConnectionTimeout(connectionTimeout)
102             .withSocketTimeout(socketTimeout)
103             .build();
104         solrClient.setRequestWriter(new BinaryRequestWriter());
105         // concurrent server
106         if (USE_CONCURRENT_SERVER) {
107             int queueSize = MCRConfiguration2
108                 .getOrThrow(SOLR_CONFIG_PREFIX + "ConcurrentUpdateSolrClient.QueueSize", Integer::parseInt);
109             int threadCount = MCRConfiguration2
110                 .getOrThrow(SOLR_CONFIG_PREFIX + "ConcurrentUpdateSolrClient.ThreadCount", Integer::parseInt);
111             concurrentClient = new ConcurrentUpdateSolrClient.Builder(coreURL)
112                 .withQueueSize(queueSize)
113                 .withConnectionTimeout(connectionTimeout)
114                 .withSocketTimeout(socketTimeout)
115                 .withThreadCount(threadCount)
116                 .build();
117             concurrentClient.setRequestWriter(new BinaryRequestWriter());
118         }
119         // shutdown handler
120         MCRShutdownHandler.getInstance().addCloseable(new MCRShutdownHandler.Closeable() {
121 
122             @Override
123             public void prepareClose() {
124             }
125 
126             @Override
127             public int getPriority() {
128                 return Integer.MIN_VALUE + 5;
129             }
130 
131             @Override
132             public void close() {
133                 shutdown();
134             }
135         });
136     }
137 
138     public String getV1CoreURL() {
139         return this.serverURL + "solr/" + this.name;
140     }
141 
142     public synchronized void shutdown() {
143         try {
144             shutdownGracefully(solrClient);
145             solrClient = null;
146         } catch (SolrServerException | IOException e) {
147             LOGGER.error("Error while shutting down SOLR client.", e);
148         }
149         try {
150             shutdownGracefully(concurrentClient);
151             concurrentClient = null;
152         } catch (SolrServerException | IOException e) {
153             LOGGER.error("Error while shutting down SOLR client.", e);
154         }
155         LOGGER.info("Solr shutdown process completed.");
156     }
157 
158     private void shutdownGracefully(SolrClient client) throws SolrServerException, IOException {
159         if (client != null) {
160             LOGGER.info("Shutting down solr client: {}", client);
161             client.commit(false, false);
162             client.close();
163         }
164     }
165 
166     /**
167      * Returns the name of the core.
168      */
169     public String getName() {
170         return name;
171     }
172 
173     public String getServerURL() {
174         return serverURL;
175     }
176 
177     /**
178      * Returns the default solr client instance. Use this for queries.
179      */
180     public HttpSolrClient getClient() {
181         return solrClient;
182     }
183 
184     /**
185      * Returns the concurrent solr client instance. Use this for indexing.
186      */
187     public SolrClient getConcurrentClient() {
188         return concurrentClient != null ? concurrentClient : solrClient;
189     }
190 
191 }