View Javadoc
1   /*
2    * Copyright 2012-2017 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.util;
17  
18  import java.io.File;
19  import java.util.function.Consumer;
20  
21  import org.codelibs.core.exception.ResourceNotFoundRuntimeException;
22  import org.codelibs.core.io.FileUtil;
23  import org.codelibs.elasticsearch.runner.net.Curl;
24  import org.codelibs.elasticsearch.runner.net.CurlResponse;
25  import org.codelibs.fess.mylasta.direction.FessConfig;
26  import org.elasticsearch.action.ActionListener;
27  import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
28  import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
29  import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
30  import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
31  import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
32  import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
33  import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
34  import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
35  import org.elasticsearch.action.index.IndexRequest;
36  import org.elasticsearch.action.support.IndicesOptions;
37  import org.elasticsearch.client.Client;
38  import org.elasticsearch.client.IndicesAdminClient;
39  import org.elasticsearch.cluster.metadata.MappingMetaData;
40  import org.elasticsearch.common.collect.ImmutableOpenMap;
41  import org.elasticsearch.common.xcontent.XContentType;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  public final class UpgradeUtil {
46      private static final Logger logger = LoggerFactory.getLogger(UpgradeUtil.class);
47  
48      private UpgradeUtil() {
49      }
50  
51      public static boolean uploadResource(final String indexConfigPath, final String indexName, final String path) {
52          final String filePath = indexConfigPath + "/" + indexName + "/" + path;
53          try {
54              final String source = FileUtil.readUTF8(filePath);
55              try (CurlResponse response =
56                      Curl.post(org.codelibs.fess.util.ResourceUtil.getElasticsearchHttpUrl() + "/_configsync/file").param("path", path)
57                              .body(source).execute()) {
58                  if (response.getHttpStatusCode() == 200) {
59                      logger.info("Register " + path + " to " + indexName);
60                      return true;
61                  } else {
62                      logger.warn("Invalid request for " + path);
63                  }
64              }
65          } catch (final Exception e) {
66              logger.warn("Failed to register " + filePath, e);
67          }
68          return false;
69      }
70  
71      public static boolean createAlias(final IndicesAdminClient indicesClient, final String indexConfigPath, final String indexName,
72              final String aliasName) {
73          final FessConfig fessConfig = ComponentUtil.getFessConfig();
74          final String aliasConfigPath = indexConfigPath + "/" + indexName + "/alias/" + aliasName + ".json";
75          try {
76              final File aliasConfigFile = org.codelibs.core.io.ResourceUtil.getResourceAsFile(aliasConfigPath);
77              if (aliasConfigFile.exists()) {
78                  final String source = FileUtil.readUTF8(aliasConfigFile);
79                  final IndicesAliasesResponse response =
80                          indicesClient.prepareAliases().addAlias(indexName, aliasName, source).execute()
81                                  .actionGet(fessConfig.getIndexIndicesTimeout());
82                  if (response.isAcknowledged()) {
83                      logger.info("Created " + aliasName + " alias for " + indexName);
84                      return true;
85                  } else if (logger.isDebugEnabled()) {
86                      logger.debug("Failed to create " + aliasName + " alias for " + indexName);
87                  }
88              }
89          } catch (final ResourceNotFoundRuntimeException e) {
90              // ignore
91          } catch (final Exception e) {
92              logger.warn(aliasConfigPath + " is not found.", e);
93          }
94          return false;
95      }
96  
97      public static boolean addMapping(final IndicesAdminClient indicesClient, final String index, final String type,
98              final String indexResourcePath) {
99          final FessConfig fessConfig = ComponentUtil.getFessConfig();
100         final GetMappingsResponse getMappingsResponse =
101                 indicesClient.prepareGetMappings(index).execute().actionGet(fessConfig.getIndexIndicesTimeout());
102         final ImmutableOpenMap<String, MappingMetaData> indexMappings = getMappingsResponse.mappings().get(index);
103         if (indexMappings == null || !indexMappings.containsKey(type)) {
104             String source = null;
105             final String mappingFile = indexResourcePath + "/" + type + ".json";
106             try {
107                 source = FileUtil.readUTF8(mappingFile);
108             } catch (final Exception e) {
109                 logger.warn(mappingFile + " is not found.", e);
110             }
111             try {
112                 final PutMappingResponse putMappingResponse =
113                         indicesClient.preparePutMapping(index).setType(type).setSource(source, XContentType.JSON).execute()
114                                 .actionGet(fessConfig.getIndexIndicesTimeout());
115                 if (putMappingResponse.isAcknowledged()) {
116                     logger.info("Created " + index + "/" + type + " mapping.");
117                     return true;
118                 } else {
119                     logger.warn("Failed to create " + index + "/" + type + " mapping.");
120                 }
121                 // TODO bulk
122             } catch (final Exception e) {
123                 logger.warn("Failed to create " + index + "/" + type + " mapping.", e);
124             }
125         }
126         return false;
127     }
128 
129     public static boolean addFieldMapping(final IndicesAdminClient indicesClient, final String index, final String type,
130             final String field, final String source) {
131         final GetFieldMappingsResponse gfmResponse =
132                 indicesClient.prepareGetFieldMappings(index).addTypes(type).setFields(field).execute().actionGet();
133         final FieldMappingMetaData fieldMappings = gfmResponse.fieldMappings(index, type, field);
134         if (fieldMappings == null || fieldMappings.isNull()) {
135             try {
136                 final PutMappingResponse pmResponse =
137                         indicesClient.preparePutMapping(index).setType(type).setSource(source, XContentType.JSON).execute().actionGet();
138                 if (!pmResponse.isAcknowledged()) {
139                     logger.warn("Failed to add " + field + " to " + index + "/" + type);
140                 } else {
141                     return true;
142                 }
143             } catch (final Exception e) {
144                 logger.warn("Failed to add " + field + " to " + index + "/" + type, e);
145             }
146         }
147         return false;
148     }
149 
150     public static boolean putMapping(final IndicesAdminClient indicesClient, final String index, final String source) {
151         return putMapping(indicesClient, index, null, source);
152     }
153 
154     public static boolean putMapping(final IndicesAdminClient indicesClient, final String index, final String type, final String source) {
155         try {
156             final PutMappingRequestBuilder builder = indicesClient.preparePutMapping(index).setSource(source, XContentType.JSON);
157             if (type != null) {
158                 builder.setType(type);
159             }
160             final PutMappingResponse pmResponse = builder.execute().actionGet();
161             if (!pmResponse.isAcknowledged()) {
162                 logger.warn("Failed to update " + index + " settings.");
163             } else {
164                 return true;
165             }
166         } catch (final Exception e) {
167             logger.warn("Failed to update " + index + " settings.", e);
168         }
169 
170         return false;
171     }
172 
173     public static boolean addData(final Client fessEsClient, final String index, final String type, final String id, final String source) {
174         try {
175             final IndexRequest indexRequest = new IndexRequest(index, type, id).source(source, XContentType.JSON);
176             fessEsClient.index(indexRequest).actionGet();
177             return true;
178         } catch (final Exception e) {
179             logger.warn("Failed to add " + id + " to " + index + "/" + type, e);
180         }
181         return false;
182     }
183 
184     public static boolean existsIndex(final IndicesAdminClient indicesClient, final String index, final IndicesOptions options) {
185         final FessConfig fessConfig = ComponentUtil.getFessConfig();
186         try {
187             final IndicesExistsResponse response =
188                     indicesClient.prepareExists(index).setIndicesOptions(options).execute().actionGet(fessConfig.getIndexSearchTimeout());
189             return response.isExists();
190         } catch (final Exception e) {
191             // ignore
192         }
193         return false;
194     }
195 
196     public static void deleteIndex(final IndicesAdminClient indicesClient, final String index, final Consumer<DeleteIndexResponse> comsumer) {
197         indicesClient.prepareDelete(index).execute(new ActionListener<DeleteIndexResponse>() {
198 
199             @Override
200             public void onResponse(final DeleteIndexResponse response) {
201                 logger.info("Deleted " + index + " index.");
202                 comsumer.accept(response);
203             }
204 
205             @Override
206             public void onFailure(final Exception e) {
207                 logger.warn("Failed to delete " + index + " index.", e);
208             }
209         });
210     }
211 }