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.commands;
20  
21  import static org.mycore.solr.MCRSolrConstants.DEFAULT_SOLR_SERVER_URL;
22  import static org.mycore.solr.MCRSolrConstants.SOLR_CONFIG_PREFIX;
23  import static org.mycore.solr.MCRSolrConstants.SOLR_CORE_NAME_SUFFIX;
24  import static org.mycore.solr.MCRSolrConstants.SOLR_CORE_PREFIX;
25  import static org.mycore.solr.MCRSolrConstants.SOLR_CORE_SERVER_SUFFIX;
26  
27  import java.text.MessageFormat;
28  import java.util.List;
29  import java.util.Locale;
30  import java.util.stream.Collectors;
31  import java.util.stream.Stream;
32  
33  import org.apache.logging.log4j.LogManager;
34  import org.apache.logging.log4j.Logger;
35  import org.apache.solr.client.solrj.impl.HttpSolrClient;
36  import org.mycore.frontend.cli.MCRAbstractCommands;
37  import org.mycore.frontend.cli.MCRObjectCommands;
38  import org.mycore.frontend.cli.annotation.MCRCommand;
39  import org.mycore.frontend.cli.annotation.MCRCommandGroup;
40  import org.mycore.solr.MCRSolrClientFactory;
41  import org.mycore.solr.MCRSolrCore;
42  import org.mycore.solr.MCRSolrUtils;
43  import org.mycore.solr.classification.MCRSolrClassificationUtil;
44  import org.mycore.solr.index.MCRSolrIndexer;
45  import org.mycore.solr.schema.MCRSolrConfigReloader;
46  import org.mycore.solr.schema.MCRSolrSchemaReloader;
47  import org.mycore.solr.search.MCRSolrSearchUtils;
48  
49  /**
50   * Class provides useful solr related commands.
51   *
52   * @author shermann
53   * @author Sebastian Hofmann
54   */
55  @MCRCommandGroup(
56      name = "SOLR Commands")
57  public class MCRSolrCommands extends MCRAbstractCommands {
58  
59      private static Logger LOGGER = LogManager.getLogger();
60  
61      /**
62       * This command displays the MyCoRe properties,
63       * which have to be set, to reload the current Solr / Solr Core configuration
64       * on the next start of the MyCoRe application.
65       */
66      @MCRCommand(
67          syntax = "show solr configuration",
68          help = "displays MyCoRe properties for the current Solr configuration",
69          order = 10)
70      public static void listConfig() {
71          LOGGER.info("List core configuration: {}{}{}{}", System.lineSeparator(),
72              SOLR_CONFIG_PREFIX + "ServerURL=" + DEFAULT_SOLR_SERVER_URL,
73              System.lineSeparator(),
74              MCRSolrClientFactory.getCoreMap().entrySet().stream().map(
75                  (entry) -> {
76                      String coreID = entry.getKey();
77                      MCRSolrCore core = entry.getValue();
78  
79                      String format = "{0}{1}{2}={3}";
80                      if (!DEFAULT_SOLR_SERVER_URL.equals(core.getServerURL())) {
81                          format += "\n{0}{1}{5}={4}";
82                      }
83  
84                      return new MessageFormat(format, Locale.ROOT).format(new String[] { SOLR_CORE_PREFIX, coreID,
85                          SOLR_CORE_NAME_SUFFIX, core.getName(), core.getServerURL(), SOLR_CORE_SERVER_SUFFIX, });
86                  }).collect(Collectors.joining("\n")));
87      }
88  
89      @MCRCommand(
90          syntax = "register solr core with name {0} on server {1} as core {2}",
91          help = "registers a Solr core within MyCoRe",
92          order = 40)
93      public static void registerSolrCore(String coreName, String server, String coreID) {
94          MCRSolrClientFactory.addCore(server, coreName, coreID);
95      }
96  
97      @MCRCommand(
98          syntax = "register solr core with name {0} as core {1}",
99          help = "registers a Solr core on the configured default Solr server within MyCoRe",
100         order = 50)
101     public static void registerSolrCore(String coreName, String coreID) {
102         MCRSolrClientFactory.addCore(DEFAULT_SOLR_SERVER_URL, coreName, coreID);
103     }
104 
105     @MCRCommand(
106         syntax = "switch solr core {0} with core {1}",
107         help = "switches between two Solr core configurations",
108         order = 60)
109     public static void switchSolrCore(String coreID1, String coreID2) {
110         MCRSolrCore core1 = getCore(coreID1);
111         MCRSolrCore core2 = getCore(coreID2);
112 
113         MCRSolrClientFactory.add(coreID1, core2);
114         MCRSolrClientFactory.add(coreID2, core1);
115     }
116 
117     /**
118      * This command recreates the managed-schema.xml and solrconfig.xml files. First it removes all
119      * schema definitions, except for some MyCoRe default types and fields. Second it parses the available
120      * MyCoRe modules and components and adds / updates / deletes the schema definition.
121      * Finally it does the same for the solrconfig.xml definition.
122      *
123      * see https://github.com/MyCoRe-Org/mycore_solr_configset_main
124      *
125      * @param coreID the core type of the core that should be reloaded; the MyCoRe default application
126      * coreID is <b>main</b>
127      */
128     @MCRCommand(
129         syntax = "reload solr configuration {0} in core {1}",
130         help = "reloads the schema and the configuration in Solr "
131             + "by using the Solr schema api for core with the id {0}",
132         order = 70)
133     public static void reloadSolrConfiguration(String configType, String coreID) {
134         MCRSolrConfigReloader.reset(configType, coreID);
135         MCRSolrSchemaReloader.reset(configType, coreID);
136         MCRSolrSchemaReloader.processSchemaFiles(configType, coreID);
137         MCRSolrConfigReloader.processConfigFiles(configType, coreID);
138     }
139 
140     @MCRCommand(
141         syntax = "rebuild solr metadata and content index in core {0}",
142         help = "rebuilds metadata and content index in Solr for core with the id {0}",
143         order = 110)
144     public static void rebuildMetadataAndContentIndex(String coreID) throws Exception {
145         MCRSolrCore core = getCore(coreID);
146         HttpSolrClient client = core.getClient();
147         MCRSolrIndexer.rebuildMetadataIndex(client);
148         MCRSolrIndexer.rebuildContentIndex(client);
149         MCRSolrIndexer.optimize(client);
150     }
151 
152     @MCRCommand(
153         syntax = "rebuild solr metadata index for all objects of type {0} in core {1}",
154         help = "rebuilds the metadata index in Solr for all objects of type {0} in core with the id {1}",
155         order = 130)
156     public static void rebuildMetadataIndexType(String type, String coreID) throws Exception {
157         MCRSolrCore core = getCore(coreID);
158         MCRSolrIndexer.rebuildMetadataIndex(type, core.getClient());
159     }
160 
161     @MCRCommand(
162         syntax = "rebuild solr metadata index for object {0} in core {1}",
163         help = "rebuilds metadata index in Solr for the given object in core with the id {1}",
164         order = 120)
165     public static void rebuildMetadataIndexObject(String object, String coreID) throws Exception {
166         MCRSolrCore core = getCore(coreID);
167         MCRSolrIndexer.rebuildMetadataIndex(Stream.of(object).collect(Collectors.toList()), core.getClient());
168     }
169 
170     @MCRCommand(
171         syntax = "rebuild solr metadata index for selected in core {0}",
172         help = "rebuilds content index in Solr for selected objects and or derivates in core with the id {0}",
173         order = 140)
174     public static void rebuildMetadataIndexForSelected(String coreID) {
175         MCRSolrCore core = getCore(coreID);
176         List<String> selectedObjects = MCRObjectCommands.getSelectedObjectIDs();
177         MCRSolrIndexer.rebuildMetadataIndex(selectedObjects, core.getClient());
178     }
179 
180     @MCRCommand(
181         syntax = "rebuild solr metadata index in core {0}",
182         help = "rebuilds metadata index in Solr in core with the id {0}",
183         order = 150)
184     public static void rebuildMetadataIndex(String coreID) {
185         MCRSolrCore core = getCore(coreID);
186         MCRSolrIndexer.rebuildMetadataIndex(core.getClient());
187     }
188 
189     @MCRCommand(
190         syntax = "rebuild solr content index for object {0} in core {1}",
191         help = "rebuilds content index in Solr for the all derivates of object with the id {0} "
192             + "in core with the id {1}",
193         order = 160)
194     public static void rebuildContentIndexObject(String objectID, String coreID) {
195         MCRSolrCore core = getCore(coreID);
196         MCRSolrIndexer.rebuildContentIndex(Stream.of(objectID).collect(Collectors.toList()), core.getClient());
197     }
198 
199     @MCRCommand(
200         syntax = "rebuild solr content index for selected in core {0}",
201         help = "rebuilds content index in Solr for alll derivates of selected objects in core with the id {0}",
202         order = 170)
203     public static void rebuildContentIndexForSelected(String coreID) {
204         MCRSolrCore core = getCore(coreID);
205         List<String> selectedObjects = MCRObjectCommands.getSelectedObjectIDs();
206         MCRSolrIndexer.rebuildContentIndex(selectedObjects, core.getClient());
207     }
208 
209     @MCRCommand(
210         syntax = "rebuild solr content index in core {0}",
211         help = "rebuilds content index in Solr in core with the id {0}",
212         order = 180)
213     public static void rebuildContentIndex(String coreID) {
214         MCRSolrCore core = getCore(coreID);
215         MCRSolrIndexer.rebuildContentIndex(core.getClient());
216     }
217 
218     @MCRCommand(
219         syntax = "rebuild solr classification index in core {0}",
220         help = "rebuilds classification index in Solr in the core with the id {0}",
221         order = 190)
222     public static void rebuildClassificationIndex(String coreID) {
223         MCRSolrCore core = getCore(coreID);
224         MCRSolrClassificationUtil.rebuildIndex(core.getClient());
225     }
226 
227     @MCRCommand(
228         syntax = "clear solr index in core {0}",
229         help = "deletes all entries from index in Solr in core with the id {0}",
230         order = 210)
231     public static void dropIndex(String coreID) throws Exception {
232         MCRSolrCore core = getCore(coreID);
233         MCRSolrIndexer.dropIndex(core.getClient());
234     }
235 
236     @MCRCommand(
237         syntax = "delete from solr index all objects of type {0} in core {1}",
238         help = "deletes all objects of type {0} from index in Solr in core with the id {1}",
239         order = 220)
240     public static void dropIndexByType(String type, String coreID) throws Exception {
241         MCRSolrCore core = getCore(coreID);
242         MCRSolrIndexer.dropIndexByType(type, core.getClient());
243     }
244 
245     @MCRCommand(
246         syntax = "delete from solr index object {0} in core {1}",
247         help = "deletes an object with id {0} from index in Solr in core with the id {1}",
248         order = 230)
249     public static void deleteByIdFromSolr(String objectID, String coreID) {
250         MCRSolrCore core = getCore(coreID);
251         MCRSolrIndexer.deleteById(core.getClient(), objectID);
252     }
253 
254     @MCRCommand(
255         syntax = "select objects with solr query {0} in core {1}",
256         help = "selects mcr objects with a solr query {0} in core with the id {1}",
257         order = 310)
258     public static void selectObjectsWithSolrQuery(String query, String coreID) throws Exception {
259         MCRSolrCore core = getCore(coreID);
260         MCRObjectCommands.setSelectedObjectIDs(MCRSolrSearchUtils.listIDs(core.getClient(), query));
261     }
262 
263     /**
264      * This command optimizes the index in Solr in a given core.
265      * The operation works like a hard commit and forces all of the index segments
266      * to be merged into a single segment first.
267      * Depending on the use cases, this operation should be performed infrequently (e.g. nightly)
268      * since it is very expensive and involves reading and re-writing the entire index.
269      */
270     @MCRCommand(
271         syntax = "optimize solr index in core {0}",
272         help = "optimizes the index in Solr in core with the id {0}. "
273             + "The operation works like a hard commit and forces all of the index segments "
274             + "to be merged into a single segment first. "
275             + "Depending on the use cases, this operation should be performed infrequently (e.g. nightly), "
276             + "since it is very expensive and involves reading and re-writing the entire index",
277         order = 410)
278     public static void optimize(String coreID) {
279         MCRSolrCore core = getCore(coreID);
280         MCRSolrIndexer.optimize(core.getClient());
281     }
282 
283     private static MCRSolrCore getCore(String coreID) {
284         return MCRSolrClientFactory.get(coreID)
285             .orElseThrow(() -> MCRSolrUtils.getCoreConfigMissingException(coreID));
286     }
287 
288     @MCRCommand(
289         syntax = "synchronize solr metadata index for all objects of type {0} in core {1}",
290         help = "synchronizes the MyCoRe store and index in Solr in core with the id {1} for objects of type {0}",
291         order = 420)
292     public static void synchronizeMetadataIndex(String objectType, String coreID) throws Exception {
293         MCRSolrCore core = getCore(coreID);
294         MCRSolrIndexer.synchronizeMetadataIndex(core.getClient(), objectType);
295     }
296 
297     @MCRCommand(
298         syntax = "synchronize solr metadata index in core {0}",
299         help = "synchronizes the MyCoRe store and index in Solr in core with the id {0}",
300         order = 430)
301     public static void synchronizeMetadataIndex(String coreID) throws Exception {
302         MCRSolrCore core = getCore(coreID);
303         MCRSolrIndexer.synchronizeMetadataIndex(core.getClient());
304     }
305 }