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.app.web.api.admin.backup;
17  
18  import static org.codelibs.core.stream.StreamUtil.stream;
19  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.CSV_EXTENTION;
20  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getBackupItems;
21  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getClickLogCsvWriteCall;
22  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getFavoriteLogCsvWriteCall;
23  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getSearchLogCsvWriteCall;
24  import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getUserInfoCsvWriteCall;
25  
26  import java.io.BufferedWriter;
27  import java.io.ByteArrayInputStream;
28  import java.io.ByteArrayOutputStream;
29  import java.io.InputStream;
30  import java.io.OutputStreamWriter;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.function.Consumer;
34  
35  import org.codelibs.elasticsearch.runner.net.Curl;
36  import org.codelibs.elasticsearch.runner.net.CurlResponse;
37  import org.codelibs.fess.app.web.api.ApiResult;
38  import org.codelibs.fess.app.web.api.ApiResult.ApiBackupFilesResponse;
39  import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
40  import org.codelibs.fess.mylasta.direction.FessConfig;
41  import org.codelibs.fess.util.ComponentUtil;
42  import org.codelibs.fess.util.ResourceUtil;
43  import org.lastaflute.web.Execute;
44  import org.lastaflute.web.response.JsonResponse;
45  import org.lastaflute.web.response.StreamResponse;
46  
47  import com.orangesignal.csv.CsvConfig;
48  import com.orangesignal.csv.CsvWriter;
49  
50  /**
51   * @author Keiichi Watanabe
52   */
53  public class ApiAdminBackupAction extends FessApiAdminAction {
54  
55      // GET /api/admin/backup/files
56      @Execute
57      public JsonResponse<ApiResult> files() {
58          final List<Map<String, String>> list = getBackupItems();
59          return asJson(new ApiBackupFilesResponse().files(list).total(list.size()).status(ApiResult.Status.OK).result());
60      }
61  
62      // GET /api/admin/backup/file/{id}
63      @Execute
64      public StreamResponse get$file(final String id) {
65          final FessConfig fessConfig = ComponentUtil.getFessConfig();
66          if (stream(fessConfig.getIndexBackupAllTargets()).get(stream -> stream.anyMatch(s -> s.equals(id)))) {
67              if (id.equals("system.properties")) {
68                  return asStream(id).contentTypeOctetStream().stream(out -> {
69                      try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
70                          ComponentUtil.getSystemProperties().store(baos, id);
71                          try (final InputStream in = new ByteArrayInputStream(baos.toByteArray())) {
72                              out.write(in);
73                          }
74                      }
75                  });
76              } else if (id.endsWith(CSV_EXTENTION)) {
77                  final String name = id.substring(0, id.length() - CSV_EXTENTION.length());
78                  if ("search_log".equals(name)) {
79                      return writeCsvResponse(id, getSearchLogCsvWriteCall());
80                  } else if ("user_info".equals(name)) {
81                      return writeCsvResponse(id, getUserInfoCsvWriteCall());
82                  } else if ("click_log".equals(name)) {
83                      return writeCsvResponse(id, getClickLogCsvWriteCall());
84                  } else if ("favorite_log".equals(name)) {
85                      return writeCsvResponse(id, getFavoriteLogCsvWriteCall());
86                  }
87              } else {
88                  final String index;
89                  final String filename;
90                  if (id.endsWith(".bulk")) {
91                      index = id.substring(0, id.length() - 5);
92                      filename = id;
93                  } else {
94                      index = id;
95                      filename = id + ".bulk";
96                  }
97                  return asStream(filename).contentTypeOctetStream().stream(
98                          out -> {
99                              try (CurlResponse response =
100                                     Curl.get(ResourceUtil.getElasticsearchHttpUrl() + "/" + index + "/_data")
101                                             .header("Content-Type", "application/json").param("format", "json").execute()) {
102                                 out.write(response.getContentAsStream());
103                             }
104                         });
105             }
106         }
107 
108         throwValidationErrorApi(messages -> messages.addErrorsCouldNotFindBackupIndex(GLOBAL));
109         return StreamResponse.asEmptyBody(); // no-op
110     }
111 
112     private StreamResponse writeCsvResponse(final String id, final Consumer<CsvWriter> writeCall) {
113         return asStream(id)
114                 .contentTypeOctetStream()
115                 .header("Pragma", "no-cache")
116                 .header("Cache-Control", "no-cache")
117                 .header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
118                 .stream(out -> {
119                     final CsvConfig cfg = new CsvConfig(',', '"', '"');
120                     cfg.setEscapeDisabled(false);
121                     cfg.setQuoteDisabled(false);
122                     try (final CsvWriter writer =
123                             new CsvWriter(new BufferedWriter(new OutputStreamWriter(out.stream(), fessConfig.getCsvFileEncoding())), cfg)) {
124                         writeCall.accept(writer);
125                         writer.flush();
126                     }
127                 });
128     }
129 }