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
54 public class ApiAdminBackupAction extends FessApiAdminAction {
55
56
57
58
59 public ApiAdminBackupAction() {
60 super();
61 }
62
63
64
65
66
67
68
69 @Execute
70 public JsonResponse<ApiResult> files() {
71 final List<Map<String, String>> list = getBackupItems();
72 return asJson(new ApiBackupFilesResponse().files(list).total(list.size()).status(ApiResult.Status.OK).result());
73 }
74
75
76
77
78
79
80
81
82
83 @Execute
84 public StreamResponse get$file(final String id) {
85 final FessConfig fessConfig = ComponentUtil.getFessConfig();
86 if (stream(fessConfig.getIndexBackupAllTargets()).get(stream -> stream.anyMatch(s -> s.equals(id)))) {
87 if ("system.properties".equals(id)) {
88 return asStream(id).contentTypeOctetStream().stream(out -> {
89 try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
90 ComponentUtil.getSystemProperties().store(baos, id);
91 try (final InputStream in = new ByteArrayInputStream(baos.toByteArray())) {
92 out.write(in);
93 }
94 }
95 });
96 }
97 if (!id.endsWith(NDJSON_EXTENTION)) {
98 final String index;
99 final String filename;
100 if (id.endsWith(".bulk")) {
101 index = id.substring(0, id.length() - 5);
102 filename = id;
103 } else {
104 index = id;
105 filename = id + ".bulk";
106 }
107 return asStream(filename).contentTypeOctetStream().stream(out -> {
108 try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out.stream(), Constants.CHARSET_UTF_8))) {
109 SearchEngineUtil.scroll(index, hit -> {
110 try {
111 writer.write("{\"index\":{\"_index\":\"" + index + "\",\"_id\":\""
112 + StringEscapeUtils.escapeJson(hit.getId()) + "\"}}\n");
113 writer.write(hit.getSourceAsString());
114 writer.write("\n");
115 } catch (final IOException e) {
116 throw new IORuntimeException(e);
117 }
118 return true;
119 });
120 writer.flush();
121 }
122 });
123 }
124 final String name = id.substring(0, id.length() - NDJSON_EXTENTION.length());
125 if ("search_log".equals(name)) {
126 return writeNdjsonResponse(id, getSearchLogNdjsonWriteCall());
127 }
128 if ("user_info".equals(name)) {
129 return writeNdjsonResponse(id, getUserInfoNdjsonWriteCall());
130 }
131 if ("click_log".equals(name)) {
132 return writeNdjsonResponse(id, getClickLogNdjsonWriteCall());
133 }
134 if ("favorite_log".equals(name)) {
135 return writeNdjsonResponse(id, getFavoriteLogNdjsonWriteCall());
136 }
137 }
138
139 throwValidationErrorApi(messages -> messages.addErrorsCouldNotFindBackupIndex(GLOBAL));
140 return StreamResponse.asEmptyBody();
141 }
142
143 private StreamResponse writeNdjsonResponse(final String id, final Consumer<Writer> writeCall) {
144 return asStream(id)
145 .header("Pragma", "no-cache")
146 .header("Cache-Control", "no-cache")
147 .header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
148 .header("Content-Type", "application/x-ndjson")
149 .stream(out -> {
150 try (final Writer writer = new BufferedWriter(new OutputStreamWriter(out.stream(), Constants.CHARSET_UTF_8))) {
151 writeCall.accept(writer);
152 writer.flush();
153 }
154 });
155 }
156 }