fix #2448 slack notification
This commit is contained in:
parent
b959b48eb8
commit
855adb6520
8 changed files with 172 additions and 33 deletions
|
@ -136,6 +136,8 @@ public class Constants extends CoreLibConstants {
|
|||
|
||||
public static final String NOTIFICATION_TO_PROPERTY = "notification.to";
|
||||
|
||||
public static final String SLACK_WEBHOOK_URLS_PROPERTY = "slack.webhook.urls";
|
||||
|
||||
public static final String USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY = "search.use.browser.locale";
|
||||
|
||||
public static final String SUGGEST_SEARCH_LOG_PROPERTY = "suggest.searchlog";
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.codelibs.fess.exception.ContainerNotAvailableException;
|
|||
import org.codelibs.fess.helper.CrawlingInfoHelper;
|
||||
import org.codelibs.fess.helper.DataIndexHelper;
|
||||
import org.codelibs.fess.helper.DuplicateHostHelper;
|
||||
import org.codelibs.fess.helper.NotificationHelper;
|
||||
import org.codelibs.fess.helper.PathMappingHelper;
|
||||
import org.codelibs.fess.helper.WebFsIndexHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
|
@ -60,6 +61,7 @@ import org.codelibs.fess.mylasta.mail.CrawlerPostcard;
|
|||
import org.codelibs.fess.timer.SystemMonitorTarget;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.ThreadDumpUtil;
|
||||
import org.dbflute.mail.send.hook.SMailCallbackContext;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
import org.elasticsearch.monitor.os.OsProbe;
|
||||
import org.elasticsearch.monitor.process.ProcessProbe;
|
||||
|
@ -378,9 +380,7 @@ public class Crawler {
|
|||
|
||||
protected void sendMail(final Map<String, String> infoMap) {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final String toStrs = fessConfig.getNotificationTo();
|
||||
if (StringUtil.isNotBlank(toStrs)) {
|
||||
final String[] toAddresses = toStrs.split(",");
|
||||
if (fessConfig.hasNotification()) {
|
||||
final Map<String, String> dataMap = new HashMap<>();
|
||||
for (final Map.Entry<String, String> entry : infoMap.entrySet()) {
|
||||
dataMap.put(StringUtil.decapitalize(entry.getKey()), entry.getValue());
|
||||
|
@ -395,34 +395,52 @@ public class Crawler {
|
|||
logger.debug("\ninfoMap: {}\ndataMap: {}", infoMap, dataMap);
|
||||
|
||||
final DynamicProperties systemProperties = ComponentUtil.getSystemProperties();
|
||||
final String toStrs = fessConfig.getNotificationTo();
|
||||
final Postbox postbox = ComponentUtil.getComponent(Postbox.class);
|
||||
CrawlerPostcard.droppedInto(postbox, postcard -> {
|
||||
postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
|
||||
postcard.addReplyTo(fessConfig.getMailReturnPath());
|
||||
stream(toAddresses).of(stream -> stream.forEach(address -> {
|
||||
postcard.addTo(address);
|
||||
}));
|
||||
postcard.setCrawlerEndTime(getValueFromMap(dataMap, "crawlerEndTime", StringUtil.EMPTY));
|
||||
postcard.setCrawlerExecTime(getValueFromMap(dataMap, "crawlerExecTime", "0"));
|
||||
postcard.setCrawlerStartTime(getValueFromMap(dataMap, "crawlerStartTime", StringUtil.EMPTY));
|
||||
postcard.setDataCrawlEndTime(getValueFromMap(dataMap, "dataCrawlEndTime", StringUtil.EMPTY));
|
||||
postcard.setDataCrawlExecTime(getValueFromMap(dataMap, "dataCrawlExecTime", "0"));
|
||||
postcard.setDataCrawlStartTime(getValueFromMap(dataMap, "dataCrawlStartTime", StringUtil.EMPTY));
|
||||
postcard.setDataIndexSize(getValueFromMap(dataMap, "dataIndexSize", "0"));
|
||||
postcard.setDataIndexExecTime(getValueFromMap(dataMap, "dataIndexExecTime", "0"));
|
||||
postcard.setHostname(getValueFromMap(dataMap, "hostname", StringUtil.EMPTY));
|
||||
postcard.setWebFsCrawlEndTime(getValueFromMap(dataMap, "webFsCrawlEndTime", StringUtil.EMPTY));
|
||||
postcard.setWebFsCrawlExecTime(getValueFromMap(dataMap, "webFsCrawlExecTime", "0"));
|
||||
postcard.setWebFsCrawlStartTime(getValueFromMap(dataMap, "webFsCrawlStartTime", StringUtil.EMPTY));
|
||||
postcard.setWebFsIndexExecTime(getValueFromMap(dataMap, "webFsIndexExecTime", "0"));
|
||||
postcard.setWebFsIndexSize(getValueFromMap(dataMap, "webFsIndexSize", "0"));
|
||||
if (Constants.TRUE.equalsIgnoreCase(infoMap.get(Constants.CRAWLER_STATUS))) {
|
||||
postcard.setStatus(Constants.OK);
|
||||
try {
|
||||
final String[] toAddresses;
|
||||
if (StringUtil.isNotBlank(toStrs)) {
|
||||
toAddresses = toStrs.split(",");
|
||||
} else {
|
||||
postcard.setStatus(Constants.FAIL);
|
||||
toAddresses = StringUtil.EMPTY_STRINGS;
|
||||
}
|
||||
postcard.setJobname(systemProperties.getProperty("job.runtime.name", StringUtil.EMPTY));
|
||||
});
|
||||
final NotificationHelper notificationHelper = ComponentUtil.getNotificationHelper();
|
||||
SMailCallbackContext.setPreparedMessageHookOnThread(notificationHelper::send);
|
||||
CrawlerPostcard.droppedInto(postbox, postcard -> {
|
||||
postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
|
||||
postcard.addReplyTo(fessConfig.getMailReturnPath());
|
||||
if (toAddresses.length > 0) {
|
||||
stream(toAddresses).of(stream -> stream.map(String::trim).forEach(address -> {
|
||||
postcard.addTo(address);
|
||||
}));
|
||||
} else {
|
||||
postcard.addTo(fessConfig.getMailFromAddress());
|
||||
postcard.dryrun();
|
||||
}
|
||||
postcard.setCrawlerEndTime(getValueFromMap(dataMap, "crawlerEndTime", StringUtil.EMPTY));
|
||||
postcard.setCrawlerExecTime(getValueFromMap(dataMap, "crawlerExecTime", "0"));
|
||||
postcard.setCrawlerStartTime(getValueFromMap(dataMap, "crawlerStartTime", StringUtil.EMPTY));
|
||||
postcard.setDataCrawlEndTime(getValueFromMap(dataMap, "dataCrawlEndTime", StringUtil.EMPTY));
|
||||
postcard.setDataCrawlExecTime(getValueFromMap(dataMap, "dataCrawlExecTime", "0"));
|
||||
postcard.setDataCrawlStartTime(getValueFromMap(dataMap, "dataCrawlStartTime", StringUtil.EMPTY));
|
||||
postcard.setDataIndexSize(getValueFromMap(dataMap, "dataIndexSize", "0"));
|
||||
postcard.setDataIndexExecTime(getValueFromMap(dataMap, "dataIndexExecTime", "0"));
|
||||
postcard.setHostname(getValueFromMap(dataMap, "hostname", StringUtil.EMPTY));
|
||||
postcard.setWebFsCrawlEndTime(getValueFromMap(dataMap, "webFsCrawlEndTime", StringUtil.EMPTY));
|
||||
postcard.setWebFsCrawlExecTime(getValueFromMap(dataMap, "webFsCrawlExecTime", "0"));
|
||||
postcard.setWebFsCrawlStartTime(getValueFromMap(dataMap, "webFsCrawlStartTime", StringUtil.EMPTY));
|
||||
postcard.setWebFsIndexExecTime(getValueFromMap(dataMap, "webFsIndexExecTime", "0"));
|
||||
postcard.setWebFsIndexSize(getValueFromMap(dataMap, "webFsIndexSize", "0"));
|
||||
if (Constants.TRUE.equalsIgnoreCase(infoMap.get(Constants.CRAWLER_STATUS))) {
|
||||
postcard.setStatus(Constants.OK);
|
||||
} else {
|
||||
postcard.setStatus(Constants.FAIL);
|
||||
}
|
||||
postcard.setJobname(systemProperties.getProperty("job.runtime.name", StringUtil.EMPTY));
|
||||
});
|
||||
} finally {
|
||||
SMailCallbackContext.clearPreparedMessageHookOnThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2012-2020 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.helper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.core.stream.StreamUtil;
|
||||
import org.codelibs.curl.Curl;
|
||||
import org.codelibs.curl.CurlResponse;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.dbflute.mail.CardView;
|
||||
import org.dbflute.mail.send.supplement.SMailPostingDiscloser;
|
||||
|
||||
public class NotificationHelper {
|
||||
private static final Logger logger = LogManager.getLogger(NotificationHelper.class);
|
||||
|
||||
protected static final String LF = "\n";
|
||||
|
||||
public void send(final CardView cardView, final SMailPostingDiscloser discloser) {
|
||||
sendToSlack(cardView, discloser);
|
||||
}
|
||||
|
||||
protected void sendToSlack(CardView cardView, SMailPostingDiscloser discloser) {
|
||||
// https://api.slack.com/messaging/webhooks#posting_with_webhooks
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final String slackWebhookUrls = fessConfig.getSlackWebhookUrls();
|
||||
if (StringUtil.isBlank(slackWebhookUrls)) {
|
||||
return;
|
||||
}
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
final String body =
|
||||
buf.append("{\"text\":\"").append(StringEscapeUtils.escapeJson(toSlackMessage(discloser))).append("\"}").toString();
|
||||
StreamUtil.split(slackWebhookUrls, "[,\\s]").of(
|
||||
stream -> stream.filter(StringUtil::isNotBlank).forEach(
|
||||
url -> {
|
||||
try (CurlResponse response = Curl.post(url).header("Content-Type", "application/json").body(body).execute()) {
|
||||
if (response.getHttpStatusCode() == 200) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Sent {} to {}.", body, url);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Failed to send {} to {}. HTTP Status is {}. {}", body, url, response.getHttpStatusCode(),
|
||||
response.getContentAsString());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
logger.warn("Failed to send {} to {}.", body, url, e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected String toSlackMessage(final SMailPostingDiscloser discloser) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(LF).append(discloser.getSavedSubject().orElse(StringUtil.EMPTY).trim());
|
||||
sb.append(LF).append("```");
|
||||
sb.append(LF).append(discloser.getSavedPlainText().orElse(StringUtil.EMPTY).trim());
|
||||
sb.append(LF).append("```");
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
}
|
|
@ -15,15 +15,19 @@
|
|||
*/
|
||||
package org.codelibs.fess.job;
|
||||
|
||||
import static org.codelibs.core.stream.StreamUtil.stream;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.entity.PingResponse;
|
||||
import org.codelibs.fess.es.client.FessEsClient;
|
||||
import org.codelibs.fess.helper.NotificationHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.mylasta.mail.EsStatusPostcard;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.dbflute.mail.send.hook.SMailCallbackContext;
|
||||
import org.lastaflute.core.mail.Postbox;
|
||||
|
||||
public class PingEsJob {
|
||||
|
@ -37,23 +41,40 @@ public class PingEsJob {
|
|||
|
||||
final StringBuilder resultBuf = new StringBuilder();
|
||||
|
||||
final String notificationTo = fessConfig.getNotificationTo();
|
||||
final PingResponse ping = fessEsClient.ping();
|
||||
final int status = ping.getStatus();
|
||||
if (systemHelper.isChangedClusterState(status)) {
|
||||
if (StringUtil.isNotBlank(notificationTo)) {
|
||||
if (fessConfig.hasNotification()) {
|
||||
final String toStrs = fessConfig.getNotificationTo();
|
||||
final String[] toAddresses;
|
||||
if (StringUtil.isNotBlank(toStrs)) {
|
||||
toAddresses = toStrs.split(",");
|
||||
} else {
|
||||
toAddresses = StringUtil.EMPTY_STRINGS;
|
||||
}
|
||||
final Postbox postbox = ComponentUtil.getComponent(Postbox.class);
|
||||
try {
|
||||
final NotificationHelper notificationHelper = ComponentUtil.getNotificationHelper();
|
||||
SMailCallbackContext.setPreparedMessageHookOnThread(notificationHelper::send);
|
||||
EsStatusPostcard.droppedInto(postbox, postcard -> {
|
||||
postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
|
||||
postcard.addReplyTo(fessConfig.getMailReturnPath());
|
||||
postcard.addTo(notificationTo);
|
||||
if (toAddresses.length > 0) {
|
||||
stream(toAddresses).of(stream -> stream.map(String::trim).forEach(address -> {
|
||||
postcard.addTo(address);
|
||||
}));
|
||||
} else {
|
||||
postcard.addTo(fessConfig.getMailFromAddress());
|
||||
postcard.dryrun();
|
||||
}
|
||||
postcard.setHostname(systemHelper.getHostname());
|
||||
postcard.setClustername(ping.getClusterName());
|
||||
postcard.setClusterstatus(ping.getClusterStatus());
|
||||
});
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Failed to send a test mail.", e);
|
||||
} finally {
|
||||
SMailCallbackContext.clearPreparedMessageHookOnThread();
|
||||
}
|
||||
}
|
||||
resultBuf.append("Status of ").append(ping.getClusterName()).append(" is changed to ").append(ping.getClusterStatus())
|
||||
|
|
|
@ -501,6 +501,18 @@ public interface FessProp {
|
|||
return getSystemProperty(Constants.PURGE_BY_BOTS_PROPERTY, Constants.DEFAULT_PURGE_BY_BOTS);
|
||||
}
|
||||
|
||||
default boolean hasNotification() {
|
||||
return StringUtil.isNotBlank(getNotificationTo()) || StringUtil.isNotBlank(getSlackWebhookUrls());
|
||||
}
|
||||
|
||||
default void getSlackWebhookUrls(final String value) {
|
||||
setSystemProperty(Constants.SLACK_WEBHOOK_URLS_PROPERTY, value);
|
||||
}
|
||||
|
||||
default String getSlackWebhookUrls() {
|
||||
return getSystemProperty(Constants.SLACK_WEBHOOK_URLS_PROPERTY, StringUtil.EMPTY);
|
||||
}
|
||||
|
||||
default void setNotificationTo(final String value) {
|
||||
setSystemProperty(Constants.NOTIFICATION_TO_PROPERTY, value);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ public class FessMailDeliveryDepartmentCreator {
|
|||
}
|
||||
|
||||
protected SMailDogmaticPostalPersonnel createDogmaticPostalPersonnel() { // #ext_point e.g. locale, database
|
||||
final String testPrefix = fessConfig.getMailSubjectTestPrefix();
|
||||
final AsyncManager asyncManager = getAsyncManager();
|
||||
final MessageManager messageManager = getMessageManager();
|
||||
return new SMailDogmaticPostalPersonnel() {
|
||||
|
@ -96,7 +95,7 @@ public class FessMailDeliveryDepartmentCreator {
|
|||
|
||||
@Override
|
||||
protected OptionalThing<SMailSubjectFilter> createSubjectFilter() {
|
||||
return OptionalThing.of((view, subject) -> testPrefix + subject);
|
||||
return OptionalThing.of((view, subject) -> subject);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.codelibs.fess.helper.JobHelper;
|
|||
import org.codelibs.fess.helper.KeyMatchHelper;
|
||||
import org.codelibs.fess.helper.LabelTypeHelper;
|
||||
import org.codelibs.fess.helper.LanguageHelper;
|
||||
import org.codelibs.fess.helper.NotificationHelper;
|
||||
import org.codelibs.fess.helper.PathMappingHelper;
|
||||
import org.codelibs.fess.helper.PermissionHelper;
|
||||
import org.codelibs.fess.helper.PluginHelper;
|
||||
|
@ -93,6 +94,8 @@ public final class ComponentUtil {
|
|||
|
||||
private static Map<String, Object> componentMap = new HashMap<>();
|
||||
|
||||
private static final String NOTIFICATION_HELPER = "notificationHelper";
|
||||
|
||||
private static final String SEARCH_HELPER = "searchHelper";
|
||||
|
||||
private static final String THEME_HELPER = "themeHelper";
|
||||
|
@ -467,6 +470,10 @@ public final class ComponentUtil {
|
|||
return getComponent(SEARCH_HELPER);
|
||||
}
|
||||
|
||||
public static NotificationHelper getNotificationHelper() {
|
||||
return getComponent(NOTIFICATION_HELPER);
|
||||
}
|
||||
|
||||
public static <T> T getComponent(final Class<T> clazz) {
|
||||
try {
|
||||
return SingletonLaContainer.getComponent(clazz);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
</component>
|
||||
<component name="indexingHelper" class="org.codelibs.fess.helper.IndexingHelper">
|
||||
</component>
|
||||
<component name="notificationHelper" class="org.codelibs.fess.helper.NotificationHelper">
|
||||
</component>
|
||||
<component name="pathMappingHelper" class="org.codelibs.fess.helper.PathMappingHelper">
|
||||
</component>
|
||||
<component name="processHelper" class="org.codelibs.fess.helper.ProcessHelper">
|
||||
|
|
Loading…
Add table
Reference in a new issue