1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.NDJSON_EXTENTION;
20 import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getBackupItems;
21 import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getClickLogNdjsonWriteCall;
22 import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getFavoriteLogNdjsonWriteCall;
23 import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getSearchLogNdjsonWriteCall;
24 import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getUserInfoNdjsonWriteCall;
25
26 import java.io.BufferedWriter;
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStreamWriter;
32 import java.io.Writer;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.function.Consumer;
36
37 import org.apache.commons.text.StringEscapeUtils;
38 import org.codelibs.core.exception.IORuntimeException;
39 import org.codelibs.fess.Constants;
40 import org.codelibs.fess.app.web.api.ApiResult;
41 import org.codelibs.fess.app.web.api.ApiResult.ApiBackupFilesResponse;
42 import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
43 import org.codelibs.fess.mylasta.direction.FessConfig;
44 import org.codelibs.fess.util.ComponentUtil;
45 import org.codelibs.fess.util.SearchEngineUtil;
46 import org.lastaflute.web.Execute;
47 import org.lastaflute.web.response.JsonResponse;
48 import org.lastaflute.web.response.StreamResponse;
49
50
51
52
53 public class ApiAdminBackupAction extends FessApiAdminAction {
54
55
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
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 ("system.properties".equals(id)) {
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 }
77 if (!id.endsWith(NDJSON_EXTENTION)) {
78 final String index;
79 final String filename;
80 if (id.endsWith(".bulk")) {
81 index = id.substring(0, id.length() - 5);
82 filename = id;
83 } else {
84 index = id;
85 filename = id + ".bulk";
86 }
87 return asStream(filename).contentTypeOctetStream().stream(out -> {
88 try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out.stream(), Constants.CHARSET_UTF_8))) {
89 SearchEngineUtil.scroll(index, hit -> {
90 try {
91 writer.write("{\"index\":{\"_index\":\"" + index + "\",\"_id\":\""
92 + StringEscapeUtils.escapeJson(hit.getId()) + "\"}}\n");
93 writer.write(hit.getSourceAsString());
94 writer.write("\n");
95 } catch (final IOException e) {
96 throw new IORuntimeException(e);
97 }
98 return true;
99 });
100 writer.flush();
101 }
102 });
103 }
104 final String name = id.substring(0, id.length() - NDJSON_EXTENTION.length());
105 if ("search_log".equals(name)) {
106 return writeNdjsonResponse(id, getSearchLogNdjsonWriteCall());
107 } else if ("user_info".equals(name)) {
108 return writeNdjsonResponse(id, getUserInfoNdjsonWriteCall());
109 } else if ("click_log".equals(name)) {
110 return writeNdjsonResponse(id, getClickLogNdjsonWriteCall());
111 } else if ("favorite_log".equals(name)) {
112 return writeNdjsonResponse(id, getFavoriteLogNdjsonWriteCall());
113 }
114 }
115
116 throwValidationErrorApi(messages -> messages.addErrorsCouldNotFindBackupIndex(GLOBAL));
117 return StreamResponse.asEmptyBody();
118 }
119
120 private StreamResponse writeNdjsonResponse(final String id, final Consumer<Writer> writeCall) {
121 return asStream(id)
122 .header("Pragma", "no-cache")
123 .header("Cache-Control", "no-cache")
124 .header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
125 .header("Content-Type", "application/x-ndjson")
126 .stream(out -> {
127 try (final Writer writer = new BufferedWriter(new OutputStreamWriter(out.stream(), Constants.CHARSET_UTF_8))) {
128 writeCall.accept(writer);
129 writer.flush();
130 }
131 });
132 }
133 }