add #963 Admin API: /api/admin/backup
This commit is contained in:
parent
49a5412e6e
commit
164a273b6d
3 changed files with 177 additions and 23 deletions
|
@ -46,6 +46,7 @@ import org.codelibs.fess.es.log.exbhv.FavoriteLogBhv;
|
|||
import org.codelibs.fess.es.log.exbhv.SearchFieldLogBhv;
|
||||
import org.codelibs.fess.es.log.exbhv.SearchLogBhv;
|
||||
import org.codelibs.fess.es.log.exbhv.UserInfoBhv;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
import org.codelibs.fess.util.ResourceUtil;
|
||||
|
@ -69,7 +70,7 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AdminBackupAction.class);
|
||||
|
||||
private static final String CSV_EXTENTION = ".csv";
|
||||
public static final String CSV_EXTENTION = ".csv";
|
||||
|
||||
private static final DateTimeFormatter ISO_8601_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
|
||||
|
@ -139,15 +140,15 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
} else if (id.endsWith(CSV_EXTENTION)) {
|
||||
final String name = id.substring(0, id.length() - CSV_EXTENTION.length());
|
||||
if ("search_log".equals(name)) {
|
||||
return writeSearchLogCsvResponse(id);
|
||||
return writeCsvResponse(id, getSearchLogCsvWriteCall());
|
||||
} else if ("search_field_log".equals(name)) {
|
||||
return writeSearchFieldLogCsvResponse(id);
|
||||
return writeCsvResponse(id, getSearchFieldLogCsvWriteCall());
|
||||
} else if ("user_info".equals(name)) {
|
||||
return writeUserInfoCsvResponse(id);
|
||||
return writeCsvResponse(id, getUserInfoCsvWriteCall());
|
||||
} else if ("click_log".equals(name)) {
|
||||
return writeClickLogCsvResponse(id);
|
||||
return writeCsvResponse(id, getClickLogCsvWriteCall());
|
||||
} else if ("favorite_log".equals(name)) {
|
||||
return writeFavoriteLogCsvResponse(id);
|
||||
return writeCsvResponse(id, getFavoriteLogCsvWriteCall());
|
||||
}
|
||||
} else {
|
||||
final String index;
|
||||
|
@ -195,8 +196,8 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
});
|
||||
}
|
||||
|
||||
private StreamResponse writeSearchLogCsvResponse(final String id) {
|
||||
return writeCsvResponse(id, writer -> {
|
||||
public static Consumer<CsvWriter> getSearchLogCsvWriteCall() {
|
||||
return writer -> {
|
||||
final SearchLogBhv bhv = ComponentUtil.getComponent(SearchLogBhv.class);
|
||||
bhv.selectCursor(cb -> {
|
||||
cb.query().matchAll();
|
||||
|
@ -226,11 +227,11 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
throw new RuntimeIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private StreamResponse writeUserInfoCsvResponse(final String id) {
|
||||
return writeCsvResponse(id, writer -> {
|
||||
public static Consumer<CsvWriter> getUserInfoCsvWriteCall() {
|
||||
return writer -> {
|
||||
final UserInfoBhv bhv = ComponentUtil.getComponent(UserInfoBhv.class);
|
||||
bhv.selectCursor(cb -> {
|
||||
cb.query().matchAll();
|
||||
|
@ -245,11 +246,11 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
throw new RuntimeIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private StreamResponse writeFavoriteLogCsvResponse(final String id) {
|
||||
return writeCsvResponse(id, writer -> {
|
||||
public static Consumer<CsvWriter> getFavoriteLogCsvWriteCall() {
|
||||
return writer -> {
|
||||
final FavoriteLogBhv bhv = ComponentUtil.getComponent(FavoriteLogBhv.class);
|
||||
bhv.selectCursor(cb -> {
|
||||
cb.query().matchAll();
|
||||
|
@ -267,11 +268,11 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
throw new RuntimeIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private StreamResponse writeClickLogCsvResponse(final String id) {
|
||||
return writeCsvResponse(id, writer -> {
|
||||
public static Consumer<CsvWriter> getClickLogCsvWriteCall() {
|
||||
return writer -> {
|
||||
final ClickLogBhv bhv = ComponentUtil.getComponent(ClickLogBhv.class);
|
||||
bhv.selectCursor(cb -> {
|
||||
cb.query().matchAll();
|
||||
|
@ -291,11 +292,11 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
throw new RuntimeIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private StreamResponse writeSearchFieldLogCsvResponse(final String id) {
|
||||
return writeCsvResponse(id, writer -> {
|
||||
public static Consumer<CsvWriter> getSearchFieldLogCsvWriteCall() {
|
||||
return writer -> {
|
||||
final SearchFieldLogBhv bhv = ComponentUtil.getComponent(SearchFieldLogBhv.class);
|
||||
bhv.selectCursor(cb -> {
|
||||
cb.query().matchAll();
|
||||
|
@ -311,10 +312,10 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
throw new RuntimeIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private void addToList(final Object value, final List<String> list) {
|
||||
private static void addToList(final Object value, final List<String> list) {
|
||||
if (value == null) {
|
||||
list.add(StringUtil.EMPTY);
|
||||
} else if (value instanceof LocalDateTime) {
|
||||
|
@ -326,7 +327,8 @@ public class AdminBackupAction extends FessAdminAction {
|
|||
}
|
||||
}
|
||||
|
||||
private List<Map<String, String>> getBackupItems() {
|
||||
static public List<Map<String, String>> getBackupItems() {
|
||||
FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
return stream(fessConfig.getIndexBackupAllTargets()).get(stream -> stream.map(name -> {
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
map.put("id", name);
|
||||
|
|
|
@ -169,6 +169,26 @@ public class ApiResult {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ApiFilesResponse extends ApiResponse {
|
||||
protected List<Map<String, String>> files;
|
||||
protected long total = 0;
|
||||
|
||||
public ApiFilesResponse backupfiles(final List<Map<String, String>> files) {
|
||||
this.files = files;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApiFilesResponse total(final long total) {
|
||||
this.total = total;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResult result() {
|
||||
return new ApiResult(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApiErrorResponse extends ApiResponse {
|
||||
protected String message;
|
||||
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2012-2017 CodeLibs Project and the Others.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.app.web.api.admin.backup;
|
||||
|
||||
import static org.codelibs.core.stream.StreamUtil.stream;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.CSV_EXTENTION;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getBackupItems;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getClickLogCsvWriteCall;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getFavoriteLogCsvWriteCall;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getSearchFieldLogCsvWriteCall;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getSearchLogCsvWriteCall;
|
||||
import static org.codelibs.fess.app.web.admin.backup.AdminBackupAction.getUserInfoCsvWriteCall;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.codelibs.elasticsearch.runner.net.Curl;
|
||||
import org.codelibs.elasticsearch.runner.net.CurlResponse;
|
||||
import org.codelibs.fess.app.web.api.ApiResult;
|
||||
import org.codelibs.fess.app.web.api.ApiResult.ApiFilesResponse;
|
||||
import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.ResourceUtil;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.JsonResponse;
|
||||
import org.lastaflute.web.response.StreamResponse;
|
||||
|
||||
import com.orangesignal.csv.CsvConfig;
|
||||
import com.orangesignal.csv.CsvWriter;
|
||||
|
||||
/**
|
||||
* @author Keiichi Watanabe
|
||||
*/
|
||||
public class ApiAdminBackupAction extends FessApiAdminAction {
|
||||
|
||||
// GET /api/admin/backup/files
|
||||
@Execute
|
||||
public JsonResponse<ApiResult> files() {
|
||||
final List<Map<String, String>> list = getBackupItems();
|
||||
return asJson(new ApiFilesResponse().backupfiles(list).total(list.size()).status(ApiResult.Status.OK).result());
|
||||
}
|
||||
|
||||
// GET /api/admin/backup/file/{id}
|
||||
@Execute
|
||||
public StreamResponse get$file(final String id) {
|
||||
FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
if (stream(fessConfig.getIndexBackupAllTargets()).get(stream -> stream.anyMatch(s -> s.equals(id)))) {
|
||||
if (id.equals("system.properties")) {
|
||||
return asStream(id).contentTypeOctetStream().stream(out -> {
|
||||
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
ComponentUtil.getSystemProperties().store(baos, id);
|
||||
try (final InputStream in = new ByteArrayInputStream(baos.toByteArray())) {
|
||||
out.write(in);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (id.endsWith(CSV_EXTENTION)) {
|
||||
final String name = id.substring(0, id.length() - CSV_EXTENTION.length());
|
||||
if ("search_log".equals(name)) {
|
||||
return writeCsvResponse(id, getSearchLogCsvWriteCall());
|
||||
} else if ("search_field_log".equals(name)) {
|
||||
return writeCsvResponse(id, getSearchFieldLogCsvWriteCall());
|
||||
} else if ("user_info".equals(name)) {
|
||||
return writeCsvResponse(id, getUserInfoCsvWriteCall());
|
||||
} else if ("click_log".equals(name)) {
|
||||
return writeCsvResponse(id, getClickLogCsvWriteCall());
|
||||
} else if ("favorite_log".equals(name)) {
|
||||
return writeCsvResponse(id, getFavoriteLogCsvWriteCall());
|
||||
}
|
||||
} else {
|
||||
final String index;
|
||||
final String filename;
|
||||
if (id.endsWith(".bulk")) {
|
||||
index = id.substring(0, id.length() - 5);
|
||||
filename = id;
|
||||
} else {
|
||||
index = id;
|
||||
filename = id + ".bulk";
|
||||
}
|
||||
return asStream(filename).contentTypeOctetStream().stream(
|
||||
out -> {
|
||||
try (CurlResponse response =
|
||||
Curl.get(ResourceUtil.getElasticsearchHttpUrl() + "/" + index + "/_data")
|
||||
.header("Content-Type", "application/json").param("format", "json").execute()) {
|
||||
out.write(response.getContentAsStream());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
throwValidationErrorApi(messages -> messages.addErrorsCouldNotFindBackupIndex(GLOBAL));
|
||||
return StreamResponse.asEmptyBody(); // no-op
|
||||
}
|
||||
|
||||
private StreamResponse writeCsvResponse(final String id, final Consumer<CsvWriter> writeCall) {
|
||||
return asStream(id)
|
||||
.contentTypeOctetStream()
|
||||
.header("Pragma", "no-cache")
|
||||
.header("Cache-Control", "no-cache")
|
||||
.header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
|
||||
.stream(out -> {
|
||||
final CsvConfig cfg = new CsvConfig(',', '"', '"');
|
||||
cfg.setEscapeDisabled(false);
|
||||
cfg.setQuoteDisabled(false);
|
||||
try (final CsvWriter writer =
|
||||
new CsvWriter(new BufferedWriter(new OutputStreamWriter(out.stream(), fessConfig.getCsvFileEncoding())), cfg)) {
|
||||
writeCall.accept(writer);
|
||||
writer.flush();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue