replace with lasta-job #349
This commit is contained in:
parent
f6108aa2d5
commit
125847d5f7
26 changed files with 471 additions and 284 deletions
18
pom.xml
18
pom.xml
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.codelibs.fess</groupId>
|
||||
<artifactId>fess</artifactId>
|
||||
|
@ -40,8 +41,9 @@
|
|||
|
||||
<!-- Main Framework -->
|
||||
<dbflute.version>1.1.1</dbflute.version>
|
||||
<lastaflute.version>0.7.8-RC2</lastaflute.version>
|
||||
<lastaflute.version>0.7.9-RC2</lastaflute.version>
|
||||
<lasta.taglib.version>0.6.8</lasta.taglib.version>
|
||||
<lasta.job.version>0.2.0-RCB</lasta.job.version>
|
||||
<servlet.version>3.1.0</servlet.version>
|
||||
<jsp.version>2.3.1</jsp.version>
|
||||
<mailflute.version>0.4.8</mailflute.version>
|
||||
|
@ -58,7 +60,7 @@
|
|||
<utflute.version>0.6.0E</utflute.version>
|
||||
|
||||
<!-- Crawler -->
|
||||
<crawler.version>1.0.2</crawler.version>
|
||||
<crawler.version>1.0.3-SNAPSHOT</crawler.version>
|
||||
|
||||
<!-- Suggest -->
|
||||
<suggest.version>2.1.1</suggest.version>
|
||||
|
@ -75,7 +77,7 @@
|
|||
<packaging.fess.app.dir>${packaging.fess.home.dir}/app</packaging.fess.app.dir>
|
||||
<packaging.fess.bin.dir>${packaging.fess.home.dir}/bin</packaging.fess.bin.dir>
|
||||
<packaging.fess.conf.dir>/etc/fess</packaging.fess.conf.dir>
|
||||
<packaging.fess.var.dir>/var/lib/fess</packaging.fess.var.dir>
|
||||
<packaging.fess.var.dir>/var/lib/fess</packaging.fess.var.dir>
|
||||
<packaging.fess.lib.dir>${packaging.fess.home.dir}/lib</packaging.fess.lib.dir>
|
||||
<packaging.fess.log.dir>/var/log/fess</packaging.fess.log.dir>
|
||||
<packaging.fess.temp.dir>/var/tmp/fess</packaging.fess.temp.dir>
|
||||
|
@ -95,7 +97,7 @@
|
|||
</resource>
|
||||
</resources>
|
||||
|
||||
<!-- This file contains all the common properties used to build the different
|
||||
<!-- This file contains all the common properties used to build the different
|
||||
packages (tar.gz, deb, rpm) using Maven resources plugin -->
|
||||
<filters>
|
||||
<filter>src/packaging/common/packaging.properties</filter>
|
||||
|
@ -759,9 +761,9 @@
|
|||
|
||||
<!-- scheduler -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<groupId>org.lastaflute.job</groupId>
|
||||
<artifactId>lasta-job</artifactId>
|
||||
<version>${lasta.job.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mail -->
|
||||
|
|
|
@ -56,6 +56,8 @@ public class Constants extends CoreLibConstants {
|
|||
|
||||
public static final String FAIL = "fail";
|
||||
|
||||
public static final String STOP = "stop";
|
||||
|
||||
public static final String ITEM_LABEL = "label";
|
||||
|
||||
public static final String ITEM_VALUE = "value";
|
||||
|
@ -66,13 +68,13 @@ public class Constants extends CoreLibConstants {
|
|||
|
||||
public static final String MS932 = "MS932";
|
||||
|
||||
public static final String DEFAULT_CRON_EXPRESSION = "0 0 0 * * ?";
|
||||
public static final String DEFAULT_CRON_EXPRESSION = "0 0 * * *";
|
||||
|
||||
public static final String DEFAULT_SEARCH_LOG_CRON_EXPRESSION = "0 * * * * ?";
|
||||
public static final String DEFAULT_SEARCH_LOG_CRON_EXPRESSION = "* * * * *";
|
||||
|
||||
public static final String DEFAULT_DAILY_CRON_EXPRESSION = "0 0 0 * * ?";
|
||||
public static final String DEFAULT_DAILY_CRON_EXPRESSION = "0 0 * * *";
|
||||
|
||||
public static final String DEFAULT_HOURLY_CRON_EXPRESSION = "0 0 * * * ?";
|
||||
public static final String DEFAULT_HOURLY_CRON_EXPRESSION = "0 * * * *";
|
||||
|
||||
public static final int DEFAULT_INTERVAL_TIME_FOR_FS = 1000;
|
||||
|
||||
|
@ -279,12 +281,9 @@ public class Constants extends CoreLibConstants {
|
|||
public static final String OPTION_QUERY_NQ = "nq";
|
||||
|
||||
// job
|
||||
public static final String JOB_ID_PREFIX = "job";
|
||||
|
||||
public static final String SCHEDULED_JOB = "scheduledJob";
|
||||
|
||||
public static final String JOB_EXECUTOR_TYPE = "jobExecutor";
|
||||
|
||||
public static final String DEFAULT_JOB_TARGET = "all";
|
||||
|
||||
public static final String DEFAULT_JOB_SCRIPT_TYPE = "groovy";
|
||||
|
|
101
src/main/java/org/codelibs/fess/app/job/AllJobScheduler.java
Normal file
101
src/main/java/org/codelibs/fess/app/job/AllJobScheduler.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.job;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.logic.AccessContextLogic;
|
||||
import org.codelibs.fess.app.service.ScheduledJobService;
|
||||
import org.codelibs.fess.es.config.exbhv.JobLogBhv;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.dbflute.optional.OptionalThing;
|
||||
import org.lastaflute.core.time.TimeManager;
|
||||
import org.lastaflute.di.core.exception.TooManyRegistrationComponentException;
|
||||
import org.lastaflute.di.core.smart.hot.HotdeployUtil;
|
||||
import org.lastaflute.job.LaCron;
|
||||
import org.lastaflute.job.LaJob;
|
||||
import org.lastaflute.job.LaJobRunner;
|
||||
import org.lastaflute.job.LaJobRuntime;
|
||||
import org.lastaflute.job.LaJobScheduler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AllJobScheduler implements LaJobScheduler {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AllJobScheduler.class);
|
||||
|
||||
protected static final String APP_TYPE = "JOB";
|
||||
|
||||
@Resource
|
||||
private TimeManager timeManager;
|
||||
|
||||
@Resource
|
||||
private FessConfig fessConfig;
|
||||
|
||||
@Resource
|
||||
private AccessContextLogic accessContextLogic;
|
||||
|
||||
@Resource
|
||||
private ScheduledJobService scheduledJobService;
|
||||
|
||||
@Resource
|
||||
private SystemHelper systemHelper;
|
||||
|
||||
protected Class<? extends LaJob> jobClass = ScriptExecutorJob.class;
|
||||
|
||||
@Override
|
||||
public void schedule(LaCron cron) {
|
||||
scheduledJobService.start(cron);
|
||||
|
||||
final String myName = fessConfig.getSchedulerTargetName();
|
||||
if (StringUtil.isNotBlank(myName)) {
|
||||
ComponentUtil.getComponent(JobLogBhv.class).queryDelete(cb -> {
|
||||
cb.query().setJobStatus_Equal(Constants.RUNNING);
|
||||
cb.query().setTarget_Equal(myName);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public LaJobRunner createRunner() {
|
||||
return new LaJobRunner() {
|
||||
@Override
|
||||
protected boolean isSuppressHotdeploy() { // TODO workaround
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actuallyRun(Class<? extends LaJob> jobType, LaJobRuntime runtime) { // TODO workaround
|
||||
try {
|
||||
super.actuallyRun(jobType, runtime);
|
||||
} catch (TooManyRegistrationComponentException e) {
|
||||
if (HotdeployUtil.isHotdeploy()) {
|
||||
logger.warn("Failed to start job {}", jobType);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.useAccessContext(resource -> {
|
||||
return accessContextLogic.create(resource, () -> OptionalThing.empty(), () -> OptionalThing.empty(), () -> APP_TYPE);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -13,50 +13,44 @@
|
|||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.job;
|
||||
package org.codelibs.fess.app.job;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.service.JobLogService;
|
||||
import org.codelibs.fess.es.config.exentity.JobLog;
|
||||
import org.codelibs.fess.es.config.exentity.ScheduledJob;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.job.JobExecutor;
|
||||
import org.codelibs.fess.job.ScheduledJobException;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.lastaflute.di.core.SingletonLaContainer;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.lastaflute.job.JobManager;
|
||||
import org.lastaflute.job.LaJob;
|
||||
import org.lastaflute.job.LaJobRuntime;
|
||||
import org.lastaflute.job.key.LaJobUnique;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TriggeredJob implements Job {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TriggeredJob.class);
|
||||
public class ScriptExecutorJob implements LaJob {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ScriptExecutorJob.class);
|
||||
|
||||
@Override
|
||||
public void execute(final JobExecutionContext context) throws JobExecutionException {
|
||||
final JobDataMap data = context.getMergedJobDataMap();
|
||||
final ScheduledJob scheduledJob = (ScheduledJob) data.get(Constants.SCHEDULED_JOB);
|
||||
|
||||
execute(scheduledJob);
|
||||
}
|
||||
|
||||
public void execute(final ScheduledJob scheduledJob) {
|
||||
public void run(LaJobRuntime runtime) {
|
||||
final ScheduledJob scheduledJob = (ScheduledJob) runtime.getParameterMap().get(Constants.SCHEDULED_JOB); // TODO null check
|
||||
final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
|
||||
final JobHelper jobHelper = ComponentUtil.getJobHelper();
|
||||
final JobManager jobManager = ComponentUtil.getJobManager();
|
||||
final JobLog jobLog = new JobLog(scheduledJob);
|
||||
final String scriptType = scheduledJob.getScriptType();
|
||||
final String script = scheduledJob.getScriptData();
|
||||
final String id = scheduledJob.getId();
|
||||
final String jobId = Constants.JOB_ID_PREFIX + id;
|
||||
final JobExecutor jobExecutor = ComponentUtil.getJobExecutor(scriptType);
|
||||
if (jobExecutor == null) {
|
||||
throw new ScheduledJobException("No jobExecutor: " + scriptType);
|
||||
}
|
||||
|
||||
if (jobHelper.startJobExecutoer(id, jobExecutor) != null) {
|
||||
if (!jobManager.findJobByUniqueOf(LaJobUnique.of(id)).isPresent()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(jobId + " is running.");
|
||||
logger.debug("Job " + id + " is running.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -67,29 +61,28 @@ public class TriggeredJob implements Job {
|
|||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Starting Job " + jobId + ". scriptType: " + scriptType + ", script: " + script);
|
||||
logger.debug("Starting Job " + id + ". scriptType: " + scriptType + ", script: " + script);
|
||||
} else if (scheduledJob.isLoggingEnabled() && logger.isInfoEnabled()) {
|
||||
logger.info("Starting Job " + jobId + ".");
|
||||
logger.info("Starting Job " + id + ".");
|
||||
}
|
||||
|
||||
final Object ret = jobExecutor.execute(script);
|
||||
if (ret == null) {
|
||||
if (scheduledJob.isLoggingEnabled() && logger.isInfoEnabled()) {
|
||||
logger.info("Finished Job " + jobId + ".");
|
||||
logger.info("Finished Job " + id + ".");
|
||||
}
|
||||
} else {
|
||||
if (scheduledJob.isLoggingEnabled() && logger.isInfoEnabled()) {
|
||||
logger.info("Finished Job " + jobId + ". The return value is:\n" + ret);
|
||||
logger.info("Finished Job " + id + ". The return value is:\n" + ret);
|
||||
}
|
||||
jobLog.setScriptResult(ret.toString());
|
||||
}
|
||||
jobLog.setJobStatus(Constants.OK);
|
||||
} catch (final Throwable t) { // NOPMD
|
||||
logger.error("Failed to execute " + jobId + ": " + script, t);
|
||||
} catch (final Throwable t) {
|
||||
logger.error("Failed to execute " + id + ": " + script, t);
|
||||
jobLog.setJobStatus(Constants.FAIL);
|
||||
jobLog.setScriptResult(systemHelper.abbreviateLongText(t.getLocalizedMessage()));
|
||||
} finally {
|
||||
jobHelper.finishJobExecutoer(id);
|
||||
jobLog.setEndTime(ComponentUtil.getSystemHelper().getCurrentTimeAsLong());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("jobLog: " + jobLog);
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.logic;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.codelibs.fess.mylasta.action.FessUserBean;
|
||||
import org.dbflute.hook.AccessContext;
|
||||
import org.dbflute.optional.OptionalThing;
|
||||
import org.lastaflute.core.time.TimeManager;
|
||||
import org.lastaflute.db.dbflute.accesscontext.AccessContextResource;
|
||||
|
||||
public class AccessContextLogic {
|
||||
|
||||
// ===================================================================================
|
||||
// Attribute
|
||||
// =========
|
||||
@Resource
|
||||
private TimeManager timeManager;
|
||||
|
||||
// ===================================================================================
|
||||
// Resource Interface
|
||||
// ==================
|
||||
@FunctionalInterface
|
||||
public static interface UserTypeSupplier {
|
||||
OptionalThing<String> supply();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface UserBeanSupplier {
|
||||
OptionalThing<FessUserBean> supply();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface AppTypeSupplier {
|
||||
String supply();
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
// Create Context
|
||||
// ==============
|
||||
public AccessContext create(AccessContextResource resource, UserTypeSupplier userTypeSupplier, UserBeanSupplier userBeanSupplier,
|
||||
AppTypeSupplier appTypeSupplier) {
|
||||
final AccessContext context = new AccessContext();
|
||||
context.setAccessLocalDateTimeProvider(() -> timeManager.currentDateTime());
|
||||
context.setAccessUserProvider(() -> buildAccessUserTrace(resource, userTypeSupplier, userBeanSupplier, appTypeSupplier));
|
||||
return context;
|
||||
}
|
||||
|
||||
private <ID> String buildAccessUserTrace(AccessContextResource resource, UserTypeSupplier userTypeSupplier,
|
||||
UserBeanSupplier userBeanSupplier, AppTypeSupplier appTypeSupplier) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(userTypeSupplier.supply().orElse("_"));
|
||||
sb.append(",").append(appTypeSupplier.supply()).append(",").append(resource.getModuleName());
|
||||
final String trace = sb.toString();
|
||||
final int columnSize = 200;
|
||||
return trace.length() > columnSize ? trace.substring(0, columnSize) : trace;
|
||||
}
|
||||
}
|
|
@ -16,27 +16,44 @@
|
|||
package org.codelibs.fess.app.service;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.codelibs.core.beans.util.BeanUtil;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.pager.SchedulerPager;
|
||||
import org.codelibs.fess.es.config.cbean.ScheduledJobCB;
|
||||
import org.codelibs.fess.es.config.exbhv.ScheduledJobBhv;
|
||||
import org.codelibs.fess.es.config.exentity.ScheduledJob;
|
||||
import org.codelibs.fess.job.JobScheduler;
|
||||
import org.codelibs.fess.job.ScheduledJobException;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.dbflute.cbean.result.PagingResultBean;
|
||||
import org.dbflute.optional.OptionalEntity;
|
||||
import org.dbflute.optional.OptionalThing;
|
||||
import org.lastaflute.job.JobManager;
|
||||
import org.lastaflute.job.LaCron;
|
||||
import org.lastaflute.job.LaScheduledJob;
|
||||
import org.lastaflute.job.key.LaJobUnique;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ScheduledJobService implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ScheduledJobService.class);
|
||||
|
||||
@Resource
|
||||
protected ScheduledJobBhv scheduledJobBhv;
|
||||
|
||||
@Resource
|
||||
protected FessConfig fessConfig;
|
||||
|
||||
public List<ScheduledJob> getScheduledJobList(final SchedulerPager scheduledJobPager) {
|
||||
|
||||
final PagingResultBean<ScheduledJob> scheduledJobList = scheduledJobBhv.selectPage(cb -> {
|
||||
|
@ -65,9 +82,6 @@ public class ScheduledJobService implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected JobScheduler jobScheduler;
|
||||
|
||||
protected void setupListCondition(final ScheduledJobCB cb, final SchedulerPager scheduledJobPager) {
|
||||
if (scheduledJobPager.id != null) {
|
||||
cb.query().docMeta().setId_Equal(scheduledJobPager.id);
|
||||
|
@ -90,15 +104,12 @@ public class ScheduledJobService implements Serializable {
|
|||
}
|
||||
|
||||
public void store(final ScheduledJob scheduledJob) {
|
||||
final boolean isNew = scheduledJob.getId() == null;
|
||||
|
||||
scheduledJobBhv.insertOrUpdate(scheduledJob, op -> {
|
||||
op.setRefresh(true);
|
||||
});
|
||||
if (!isNew) {
|
||||
jobScheduler.unregister(scheduledJob);
|
||||
}
|
||||
jobScheduler.register(scheduledJob);
|
||||
JobManager jobManager = ComponentUtil.getJobManager();
|
||||
jobManager.schedule(cron -> register(cron, scheduledJob));
|
||||
}
|
||||
|
||||
public List<ScheduledJob> getCrawlerJobList() {
|
||||
|
@ -109,4 +120,99 @@ public class ScheduledJobService implements Serializable {
|
|||
});
|
||||
}
|
||||
|
||||
protected void register(LaCron cron, final ScheduledJob scheduledJob) {
|
||||
if (scheduledJob == null) {
|
||||
throw new ScheduledJobException("No job.");
|
||||
}
|
||||
|
||||
final String id = scheduledJob.getId();
|
||||
if (!Constants.T.equals(scheduledJob.getAvailable())) {
|
||||
logger.info("Inactive Job " + id + ":" + scheduledJob.getName());
|
||||
try {
|
||||
unregister(scheduledJob);
|
||||
} catch (final Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String target = scheduledJob.getTarget();
|
||||
if (!isTarget(target)) {
|
||||
logger.info("Ignore Job " + id + ":" + scheduledJob.getName() + " because of not target: " + scheduledJob.getTarget());
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
|
||||
logger.info("Starting Job " + id + ":" + scheduledJob.getName());
|
||||
findJobByUniqueOf(LaJobUnique.of(id)).ifPresent(job -> {
|
||||
job.reschedule(scheduledJob.getCronExpression(), option -> option.uniqueBy(id).changeNoticeLogToDebug().params(() -> {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(Constants.SCHEDULED_JOB, scheduledJob);
|
||||
return params;
|
||||
}));
|
||||
}).orElse(
|
||||
() -> {
|
||||
cron.register(scheduledJob.getCronExpression(), fessConfig.getSchedulerJobClassAsClass(),
|
||||
fessConfig.getSchedulerConcurrentExecModeAsEnum(), option -> option.uniqueBy(id).changeNoticeLogToDebug()
|
||||
.params(() -> {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put(Constants.SCHEDULED_JOB, scheduledJob);
|
||||
return params;
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
logger.info("Inactive Job " + id + ":" + scheduledJob.getName());
|
||||
unregister(scheduledJob);
|
||||
}
|
||||
}
|
||||
|
||||
private OptionalThing<LaScheduledJob> findJobByUniqueOf(LaJobUnique jobUnique) {
|
||||
final JobManager jobManager = ComponentUtil.getJobManager();
|
||||
try {
|
||||
return jobManager.findJobByUniqueOf(jobUnique);
|
||||
} catch (Exception e) {
|
||||
return OptionalThing.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister(final ScheduledJob scheduledJob) {
|
||||
try {
|
||||
JobManager jobManager = ComponentUtil.getJobManager();
|
||||
jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
|
||||
job.unschedule();
|
||||
}).orElse(() -> logger.debug("Job {} is not scheduled.", scheduledJob.getId()));
|
||||
} catch (final Exception e) {
|
||||
throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTarget(final String target) {
|
||||
if (StringUtil.isBlank(target))
|
||||
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final String myName = fessConfig.getSchedulerTargetName();
|
||||
|
||||
final String[] targets = target.split(",");
|
||||
for (String name : targets) {
|
||||
name = name.trim();
|
||||
if (Constants.DEFAULT_JOB_TARGET.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
} else if (StringUtil.isNotBlank(myName) && myName.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void start(LaCron cron) {
|
||||
scheduledJobBhv.selectCursor(cb -> {
|
||||
cb.query().setAvailable_Equal(Constants.T);
|
||||
cb.query().addOrderBy_SortOrder_Asc();
|
||||
cb.query().addOrderBy_Name_Asc();
|
||||
}, scheduledJob -> register(cron, scheduledJob));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.codelibs.fess.app.pager.CrawlingInfoPager;
|
|||
import org.codelibs.fess.app.service.CrawlingInfoService;
|
||||
import org.codelibs.fess.app.web.CrudMode;
|
||||
import org.codelibs.fess.app.web.base.FessAdminAction;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
import org.lastaflute.web.Execute;
|
||||
|
@ -46,7 +46,7 @@ public class AdminCrawlinginfoAction extends FessAdminAction {
|
|||
@Resource
|
||||
private SystemHelper systemHelper;
|
||||
@Resource
|
||||
protected JobHelper jobHelper;
|
||||
protected ProcessHelper processHelper;
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
|
@ -154,7 +154,7 @@ public class AdminCrawlinginfoAction extends FessAdminAction {
|
|||
@Execute
|
||||
public HtmlResponse deleteall() {
|
||||
verifyToken(() -> asListHtml());
|
||||
crawlingInfoService.deleteOldSessions(jobHelper.getRunningSessionIdSet());
|
||||
crawlingInfoService.deleteOldSessions(processHelper.getRunningSessionIdSet());
|
||||
crawlingInfoPager.clear();
|
||||
saveInfo(messages -> messages.addSuccessCrawlingInfoDeleteAll(GLOBAL));
|
||||
return redirect(getClass());
|
||||
|
|
|
@ -25,9 +25,8 @@ import org.codelibs.fess.app.service.ScheduledJobService;
|
|||
import org.codelibs.fess.app.web.CrudMode;
|
||||
import org.codelibs.fess.app.web.base.FessAdminAction;
|
||||
import org.codelibs.fess.es.config.exentity.ScheduledJob;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.job.JobExecutor;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
import org.dbflute.optional.OptionalEntity;
|
||||
import org.dbflute.optional.OptionalThing;
|
||||
|
@ -53,7 +52,7 @@ public class AdminSchedulerAction extends FessAdminAction {
|
|||
@Resource
|
||||
private SystemHelper systemHelper;
|
||||
@Resource
|
||||
protected JobHelper jobHelper;
|
||||
protected ProcessHelper processHelper;
|
||||
|
||||
// ===================================================================================
|
||||
// Hook
|
||||
|
@ -271,8 +270,7 @@ public class AdminSchedulerAction extends FessAdminAction {
|
|||
verifyToken(() -> asDetailsHtml(id));
|
||||
scheduledJobService.getScheduledJob(id).ifPresent(entity -> {
|
||||
try {
|
||||
final JobExecutor jobExecutoer = jobHelper.getJobExecutoer(entity.getId());
|
||||
jobExecutoer.shutdown();
|
||||
entity.stop();
|
||||
saveInfo(messages -> messages.addSuccessJobStopped(GLOBAL, entity.getName()));
|
||||
} catch (final Exception e) {
|
||||
throwValidationError(messages -> {
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.codelibs.fess.entity.SearchRenderData;
|
|||
import org.codelibs.fess.es.client.FessEsClient;
|
||||
import org.codelibs.fess.exception.InvalidQueryException;
|
||||
import org.codelibs.fess.exception.ResultOffsetExceededException;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.QueryHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.util.RenderDataUtil;
|
||||
|
@ -66,7 +66,7 @@ public class AdminSearchlistAction extends FessAdminAction {
|
|||
protected QueryHelper queryHelper;
|
||||
|
||||
@Resource
|
||||
protected JobHelper jobHelper;
|
||||
protected ProcessHelper processHelper;
|
||||
|
||||
@Resource
|
||||
protected SearchService searchService;
|
||||
|
@ -194,7 +194,7 @@ public class AdminSearchlistAction extends FessAdminAction {
|
|||
verifyToken(() -> asListHtml());
|
||||
validate(form, messages -> {}, () -> asListHtml());
|
||||
final String docId = form.docId;
|
||||
if (jobHelper.isProcessRunning()) {
|
||||
if (processHelper.isProcessRunning()) {
|
||||
throwValidationError(messages -> messages.addErrorsCannotDeleteDocBecauseOfRunning(GLOBAL), () -> asListHtml());
|
||||
}
|
||||
try {
|
||||
|
@ -211,7 +211,7 @@ public class AdminSearchlistAction extends FessAdminAction {
|
|||
public HtmlResponse deleteall(final ListForm form) {
|
||||
verifyToken(() -> asListHtml());
|
||||
validate(form, messages -> {}, () -> asListHtml());
|
||||
if (jobHelper.isProcessRunning()) {
|
||||
if (processHelper.isProcessRunning()) {
|
||||
throwValidationError(messages -> messages.addErrorsCannotDeleteDocBecauseOfRunning(GLOBAL), () -> asListHtml());
|
||||
}
|
||||
try {
|
||||
|
@ -227,7 +227,7 @@ public class AdminSearchlistAction extends FessAdminAction {
|
|||
}
|
||||
|
||||
public boolean isSolrProcessRunning() {
|
||||
return jobHelper.isProcessRunning();
|
||||
return processHelper.isProcessRunning();
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
|
|
|
@ -33,11 +33,12 @@ import org.codelibs.fess.crawler.util.CharUtil;
|
|||
import org.codelibs.fess.es.config.exentity.FileConfig;
|
||||
import org.codelibs.fess.es.config.exentity.ScheduledJob;
|
||||
import org.codelibs.fess.es.config.exentity.WebConfig;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.job.TriggeredJob;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.StreamUtil;
|
||||
import org.lastaflute.job.JobManager;
|
||||
import org.lastaflute.job.key.LaJobUnique;
|
||||
import org.lastaflute.web.Execute;
|
||||
import org.lastaflute.web.response.HtmlResponse;
|
||||
import org.lastaflute.web.ruts.process.ActionRuntime;
|
||||
|
@ -67,7 +68,7 @@ public class AdminWizardAction extends FessAdminAction {
|
|||
protected SystemHelper systemHelper;
|
||||
|
||||
@Resource
|
||||
protected JobHelper jobHelper;
|
||||
protected ProcessHelper processHelper;
|
||||
|
||||
@Resource
|
||||
protected ScheduledJobService scheduledJobService;
|
||||
|
@ -289,10 +290,13 @@ public class AdminWizardAction extends FessAdminAction {
|
|||
@Execute
|
||||
public HtmlResponse startCrawling(final StartCrawlingForm form) {
|
||||
verifyToken(() -> asIndexHtml());
|
||||
if (!jobHelper.isProcessRunning()) {
|
||||
if (!processHelper.isProcessRunning()) {
|
||||
final List<ScheduledJob> scheduledJobList = scheduledJobService.getCrawlerJobList();
|
||||
JobManager jobManager = ComponentUtil.getJobManager();
|
||||
for (final ScheduledJob scheduledJob : scheduledJobList) {
|
||||
new Thread(() -> new TriggeredJob().execute(scheduledJob)).start();
|
||||
jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
|
||||
job.launchNow();
|
||||
});
|
||||
}
|
||||
saveInfo(messages -> messages.addSuccessStartCrawlProcess(GLOBAL));
|
||||
} else {
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
package org.codelibs.fess.es.config.exentity;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.es.config.bsentity.BsScheduledJob;
|
||||
import org.codelibs.fess.job.TriggeredJob;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.lastaflute.job.key.LaJobUnique;
|
||||
|
||||
/**
|
||||
* @author FreeGen
|
||||
|
@ -27,6 +28,14 @@ public class ScheduledJob extends BsScheduledJob {
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String getScriptType() {
|
||||
String st = super.getScriptType();
|
||||
if (StringUtil.isBlank(st)) {
|
||||
return "groovy";
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
public boolean isLoggingEnabled() {
|
||||
return Constants.T.equals(getJobLogging());
|
||||
}
|
||||
|
@ -40,12 +49,19 @@ public class ScheduledJob extends BsScheduledJob {
|
|||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return ComponentUtil.getJobHelper().getJobExecutoer(getId()) != null;
|
||||
return ComponentUtil.getJobManager().findJobByUniqueOf(LaJobUnique.of(getId())).map(job -> job.isExecutingNow()).orElse(false);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
final ScheduledJob scheduledJob = this;
|
||||
new Thread(() -> new TriggeredJob().execute(scheduledJob)).start();
|
||||
ComponentUtil.getJobManager().findJobByUniqueOf(LaJobUnique.of(getId())).ifPresent(job -> {
|
||||
job.launchNow();
|
||||
});
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
ComponentUtil.getJobManager().findJobByUniqueOf(LaJobUnique.of(getId())).ifPresent(job -> {
|
||||
job.stopNow();
|
||||
});
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
|
|
@ -27,19 +27,16 @@ import javax.annotation.PreDestroy;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.codelibs.fess.exception.FessSystemException;
|
||||
import org.codelibs.fess.job.JobExecutor;
|
||||
import org.codelibs.fess.util.InputStreamThread;
|
||||
import org.codelibs.fess.util.JobProcess;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JobHelper {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobHelper.class);
|
||||
public class ProcessHelper {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProcessHelper.class);
|
||||
|
||||
private final ConcurrentHashMap<String, JobProcess> runningProcessMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final ConcurrentHashMap<String, JobExecutor> runningJobExecutorMap = new ConcurrentHashMap<>();
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
for (final String sessionId : runningProcessMap.keySet()) {
|
||||
|
@ -117,16 +114,4 @@ public class JobHelper {
|
|||
return runningProcessMap.keySet();
|
||||
}
|
||||
|
||||
public JobExecutor startJobExecutoer(final String id, final JobExecutor jobExecutor) {
|
||||
return runningJobExecutorMap.putIfAbsent(id, jobExecutor);
|
||||
}
|
||||
|
||||
public void finishJobExecutoer(final String id) {
|
||||
runningJobExecutorMap.remove(id);
|
||||
}
|
||||
|
||||
public JobExecutor getJobExecutoer(final String id) {
|
||||
return runningJobExecutorMap.get(id);
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.lang3.LocaleUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -49,6 +50,8 @@ import org.codelibs.fess.util.ComponentUtil;
|
|||
import org.lastaflute.di.core.SingletonLaContainer;
|
||||
import org.lastaflute.web.servlet.request.RequestManager;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
@ -56,6 +59,7 @@ import com.google.common.cache.LoadingCache;
|
|||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
public class SystemHelper implements Serializable {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SystemHelper.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -71,6 +75,8 @@ public class SystemHelper implements Serializable {
|
|||
|
||||
private String[] supportedLanguages;
|
||||
|
||||
private List<Runnable> shutdownHookList = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
|
@ -103,6 +109,17 @@ public class SystemHelper implements Serializable {
|
|||
});
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
shutdownHookList.forEach(action -> {
|
||||
try {
|
||||
action.run();
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to process shutdown task.", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
final RequestManager requestManager = ComponentUtil.getRequestManager();
|
||||
return requestManager.findUserBean(FessUserBean.class).map(user -> {
|
||||
|
@ -252,4 +269,16 @@ public class SystemHelper implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public void sleep(int sec) {
|
||||
try {
|
||||
Thread.sleep(sec * 1000L);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void addShutdownHook(Runnable hook) {
|
||||
shutdownHookList.add(hook);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.codelibs.core.lang.StringUtil;
|
|||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.exception.FessSystemException;
|
||||
import org.codelibs.fess.exec.Crawler;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
|
@ -231,7 +231,7 @@ public class CrawlJob {
|
|||
final String cpSeparator = SystemUtils.IS_OS_WINDOWS ? ";" : ":";
|
||||
final ServletContext servletContext = SingletonLaContainer.getComponent(ServletContext.class);
|
||||
final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
|
||||
final JobHelper jobHelper = ComponentUtil.getJobHelper();
|
||||
final ProcessHelper processHelper = ComponentUtil.getJobHelper();
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
|
||||
cmdList.add(fessConfig.getJavaCommandPath());
|
||||
|
@ -361,7 +361,7 @@ public class CrawlJob {
|
|||
logger.info("Crawler: \nDirectory=" + baseDir + "\nOptions=" + cmdList);
|
||||
}
|
||||
|
||||
final JobProcess jobProcess = jobHelper.startProcess(sessionId, cmdList, pb -> {
|
||||
final JobProcess jobProcess = processHelper.startProcess(sessionId, cmdList, pb -> {
|
||||
pb.directory(baseDir);
|
||||
pb.redirectErrorStream(true);
|
||||
});
|
||||
|
@ -389,7 +389,7 @@ public class CrawlJob {
|
|||
throw new FessSystemException("Crawler Process terminated.", e);
|
||||
} finally {
|
||||
try {
|
||||
jobHelper.destroyProcess(sessionId);
|
||||
processHelper.destroyProcess(sessionId);
|
||||
} finally {
|
||||
if (propFile != null && !propFile.delete()) {
|
||||
logger.warn("Failed to delete {}.", propFile.getAbsolutePath());
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.job;
|
||||
|
||||
import static org.quartz.CronScheduleBuilder.cronSchedule;
|
||||
import static org.quartz.JobBuilder.newJob;
|
||||
import static org.quartz.JobKey.jobKey;
|
||||
import static org.quartz.TriggerBuilder.newTrigger;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.es.config.exbhv.JobLogBhv;
|
||||
import org.codelibs.fess.es.config.exbhv.ScheduledJobBhv;
|
||||
import org.codelibs.fess.es.config.exentity.ScheduledJob;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.SchedulerFactory;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.impl.StdSchedulerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JobScheduler {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobScheduler.class);
|
||||
|
||||
private static final String TRIGGER_ID_PREFIX = "trigger";
|
||||
|
||||
private Scheduler scheduler;
|
||||
|
||||
public Class<? extends Job> jobClass = TriggeredJob.class;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
final SchedulerFactory sf = new StdSchedulerFactory();
|
||||
try {
|
||||
scheduler = sf.getScheduler();
|
||||
scheduler.start();
|
||||
} catch (final SchedulerException e) {
|
||||
throw new ScheduledJobException("Failed to start a scheduler.", e);
|
||||
}
|
||||
|
||||
ComponentUtil.getComponent(ScheduledJobBhv.class).selectCursor(cb -> {
|
||||
cb.query().setAvailable_Equal(Constants.T);
|
||||
cb.query().addOrderBy_SortOrder_Asc();
|
||||
cb.query().addOrderBy_Name_Asc();
|
||||
}, scheduledJob -> register(scheduledJob));
|
||||
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final String myName = fessConfig.getSchedulerTargetName();
|
||||
if (StringUtil.isNotBlank(myName)) {
|
||||
ComponentUtil.getComponent(JobLogBhv.class).queryDelete(cb -> {
|
||||
cb.query().setJobStatus_Equal(Constants.RUNNING);
|
||||
cb.query().setTarget_Equal(myName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
final JobHelper jobHelper = ComponentUtil.getJobHelper();
|
||||
for (final String sessionId : jobHelper.getRunningSessionIdSet()) {
|
||||
jobHelper.destroyProcess(sessionId);
|
||||
}
|
||||
try {
|
||||
scheduler.shutdown(true);
|
||||
} catch (final SchedulerException e) {
|
||||
logger.error("Failed to shutdown the scheduler.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void register(final ScheduledJob scheduledJob) {
|
||||
if (scheduledJob == null) {
|
||||
throw new ScheduledJobException("No job.");
|
||||
}
|
||||
|
||||
if (!Constants.T.equals(scheduledJob.getAvailable())) {
|
||||
logger.info("Inactive Job " + scheduledJob.getId() + ":" + scheduledJob.getName());
|
||||
try {
|
||||
unregister(scheduledJob);
|
||||
} catch (final Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String target = scheduledJob.getTarget();
|
||||
if (!isTarget(target)) {
|
||||
logger.info("Ignore Job " + scheduledJob.getId() + ":" + scheduledJob.getName() + " because of not target: "
|
||||
+ scheduledJob.getTarget());
|
||||
return;
|
||||
}
|
||||
|
||||
String scriptType = scheduledJob.getScriptType();
|
||||
if (scriptType == null) {
|
||||
scriptType = "groovy";
|
||||
}
|
||||
|
||||
final String id = scheduledJob.getId();
|
||||
final String jobId = Constants.JOB_ID_PREFIX + id;
|
||||
final String triggerId = TRIGGER_ID_PREFIX + id;
|
||||
|
||||
final JobDataMap jobDataMap = new JobDataMap();
|
||||
jobDataMap.put(Constants.SCHEDULED_JOB, scheduledJob);
|
||||
jobDataMap.put(Constants.JOB_EXECUTOR_TYPE, scriptType);
|
||||
final JobDetail jobDetail = newJob(jobClass).withIdentity(jobId).usingJobData(jobDataMap).build();
|
||||
|
||||
if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
|
||||
final Trigger trigger =
|
||||
newTrigger().withIdentity(triggerId).withSchedule(cronSchedule(scheduledJob.getCronExpression())).startNow().build();
|
||||
|
||||
try {
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (final SchedulerException e) {
|
||||
throw new ScheduledJobException("Failed to add Job: " + scheduledJob, e);
|
||||
}
|
||||
|
||||
logger.info("Starting Job " + scheduledJob.getId() + ":" + scheduledJob.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister(final ScheduledJob scheduledJob) {
|
||||
final String jobId = Constants.JOB_ID_PREFIX + scheduledJob.getId();
|
||||
try {
|
||||
scheduler.deleteJob(jobKey(jobId));
|
||||
} catch (final SchedulerException e) {
|
||||
throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTarget(final String target) {
|
||||
if (StringUtil.isBlank(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
final String myName = fessConfig.getSchedulerTargetName();
|
||||
|
||||
final String[] targets = target.split(",");
|
||||
for (String name : targets) {
|
||||
name = name.trim();
|
||||
if (Constants.DEFAULT_JOB_TARGET.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
} else if (StringUtil.isNotBlank(myName) && myName.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ import org.codelibs.core.lang.StringUtil;
|
|||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.exception.FessSystemException;
|
||||
import org.codelibs.fess.exec.SuggestCreator;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.InputStreamThread;
|
||||
|
@ -122,7 +122,7 @@ public class SuggestJob {
|
|||
final List<String> cmdList = new ArrayList<>();
|
||||
final String cpSeparator = SystemUtils.IS_OS_WINDOWS ? ";" : ":";
|
||||
final ServletContext servletContext = SingletonLaContainer.getComponent(ServletContext.class);
|
||||
final JobHelper jobHelper = ComponentUtil.getJobHelper();
|
||||
final ProcessHelper processHelper = ComponentUtil.getJobHelper();
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
|
||||
cmdList.add(fessConfig.getJavaCommandPath());
|
||||
|
@ -233,7 +233,7 @@ public class SuggestJob {
|
|||
logger.info("SuggestCreator: \nDirectory=" + baseDir + "\nOptions=" + cmdList);
|
||||
}
|
||||
|
||||
final JobProcess jobProcess = jobHelper.startProcess(sessionId, cmdList, pb -> {
|
||||
final JobProcess jobProcess = processHelper.startProcess(sessionId, cmdList, pb -> {
|
||||
pb.directory(baseDir);
|
||||
pb.redirectErrorStream(true);
|
||||
});
|
||||
|
@ -261,7 +261,7 @@ public class SuggestJob {
|
|||
throw new FessSystemException("SuggestCreator Process terminated.", e);
|
||||
} finally {
|
||||
try {
|
||||
jobHelper.destroyProcess(sessionId);
|
||||
processHelper.destroyProcess(sessionId);
|
||||
} finally {
|
||||
if (propFile != null && !propFile.delete()) {
|
||||
logger.warn("Failed to delete {}.", propFile.getAbsolutePath());
|
||||
|
|
|
@ -384,6 +384,12 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
/** The key of the configuration. e.g. */
|
||||
String SCHEDULER_TARGET_NAME = "scheduler.target.name";
|
||||
|
||||
/** The key of the configuration. e.g. org.codelibs.fess.app.job.ScriptExecutorJob */
|
||||
String SCHEDULER_JOB_CLASS = "scheduler.job.class";
|
||||
|
||||
/** The key of the configuration. e.g. QUIT */
|
||||
String SCHEDULER_CONCURRENT_EXEC_MODE = "scheduler.concurrent.exec.mode";
|
||||
|
||||
/** The key of the configuration. e.g. http://fess.codelibs.org/{lang}/{version}/admin/ */
|
||||
String ONLINE_HELP_BASE_LINK = "online.help.base.link";
|
||||
|
||||
|
@ -1773,6 +1779,20 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
*/
|
||||
Integer getSchedulerTargetNameAsInteger();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'scheduler.job.class'. <br>
|
||||
* The value is, e.g. org.codelibs.fess.app.job.ScriptExecutorJob <br>
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getSchedulerJobClass();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'scheduler.concurrent.exec.mode'. <br>
|
||||
* The value is, e.g. QUIT <br>
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getSchedulerConcurrentExecMode();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'online.help.base.link'. <br>
|
||||
* The value is, e.g. http://fess.codelibs.org/{lang}/{version}/admin/ <br>
|
||||
|
@ -2834,6 +2854,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
|
|||
return getAsInteger(FessConfig.SCHEDULER_TARGET_NAME);
|
||||
}
|
||||
|
||||
public String getSchedulerJobClass() {
|
||||
return get(FessConfig.SCHEDULER_JOB_CLASS);
|
||||
}
|
||||
|
||||
public String getSchedulerConcurrentExecMode() {
|
||||
return get(FessConfig.SCHEDULER_CONCURRENT_EXEC_MODE);
|
||||
}
|
||||
|
||||
public String getOnlineHelpBaseLink() {
|
||||
return get(FessConfig.ONLINE_HELP_BASE_LINK);
|
||||
}
|
||||
|
|
|
@ -15,10 +15,13 @@
|
|||
*/
|
||||
package org.codelibs.fess.mylasta.direction;
|
||||
|
||||
import org.codelibs.core.exception.ClassNotFoundRuntimeException;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.StreamUtil;
|
||||
import org.lastaflute.job.LaJob;
|
||||
import org.lastaflute.job.subsidiary.ConcurrentExec;
|
||||
|
||||
public interface FessProp {
|
||||
|
||||
|
@ -280,4 +283,22 @@ public interface FessProp {
|
|||
return "None";
|
||||
}
|
||||
|
||||
String getSchedulerJobClass();
|
||||
|
||||
public default Class<? extends LaJob> getSchedulerJobClassAsClass() {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends LaJob> clazz = (Class<? extends LaJob>) Class.forName(getSchedulerJobClass());
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ClassNotFoundRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getSchedulerConcurrentExecMode();
|
||||
|
||||
public default ConcurrentExec getSchedulerConcurrentExecModeAsEnum() {
|
||||
return ConcurrentExec.valueOf(getSchedulerConcurrentExecMode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ import org.codelibs.fess.helper.DuplicateHostHelper;
|
|||
import org.codelibs.fess.helper.FileTypeHelper;
|
||||
import org.codelibs.fess.helper.IndexingHelper;
|
||||
import org.codelibs.fess.helper.IntervalControlHelper;
|
||||
import org.codelibs.fess.helper.JobHelper;
|
||||
import org.codelibs.fess.helper.KeyMatchHelper;
|
||||
import org.codelibs.fess.helper.LabelTypeHelper;
|
||||
import org.codelibs.fess.helper.PathMappingHelper;
|
||||
import org.codelibs.fess.helper.PopularWordHelper;
|
||||
import org.codelibs.fess.helper.ProcessHelper;
|
||||
import org.codelibs.fess.helper.QueryHelper;
|
||||
import org.codelibs.fess.helper.RoleQueryHelper;
|
||||
import org.codelibs.fess.helper.SambaHelper;
|
||||
|
@ -51,6 +51,7 @@ import org.codelibs.fess.mylasta.direction.FessConfig;
|
|||
import org.lastaflute.core.message.MessageManager;
|
||||
import org.lastaflute.di.core.SingletonLaContainer;
|
||||
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
|
||||
import org.lastaflute.job.JobManager;
|
||||
import org.lastaflute.web.servlet.request.RequestManager;
|
||||
|
||||
public final class ComponentUtil {
|
||||
|
@ -86,7 +87,7 @@ public final class ComponentUtil {
|
|||
|
||||
private static final String WEB_API_MANAGER_FACTORY = "webApiManagerFactory";
|
||||
|
||||
private static final String JOB_HELPER = "jobHelper";
|
||||
private static final String JOB_HELPER = "processHelper";
|
||||
|
||||
private static final String DUPLICATE_HOST_HELPER = "duplicateHostHelper";
|
||||
|
||||
|
@ -187,7 +188,7 @@ public final class ComponentUtil {
|
|||
return SingletonLaContainer.getComponent(DUPLICATE_HOST_HELPER);
|
||||
}
|
||||
|
||||
public static JobHelper getJobHelper() {
|
||||
public static ProcessHelper getJobHelper() {
|
||||
return SingletonLaContainer.getComponent(JOB_HELPER);
|
||||
}
|
||||
|
||||
|
@ -279,6 +280,10 @@ public final class ComponentUtil {
|
|||
return SingletonLaContainer.getComponent(RequestManager.class);
|
||||
}
|
||||
|
||||
public static JobManager getJobManager() {
|
||||
return SingletonLaContainer.getComponent(JobManager.class);
|
||||
}
|
||||
|
||||
public static <T> T getComponent(final Class<T> clazz) {
|
||||
return SingletonLaContainer.getComponent(clazz);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import javax.validation.ConstraintValidator;
|
|||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.lastaflute.job.util.LaCronUtil;
|
||||
|
||||
public class CronExpressionValidator implements ConstraintValidator<CronExpression, String> {
|
||||
|
||||
|
@ -32,7 +33,7 @@ public class CronExpressionValidator implements ConstraintValidator<CronExpressi
|
|||
}
|
||||
|
||||
protected boolean determineValid(final String value) {
|
||||
if (StringUtil.isNotBlank(value) && !org.quartz.CronExpression.isValidExpression(value)) {
|
||||
if (StringUtil.isNotBlank(value) && !LaCronUtil.isCronExpValid(value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<components>
|
||||
<include path="convention.xml"/>
|
||||
<include path="lastaflute.xml"/>
|
||||
<include path="lasta_job.xml"/>
|
||||
|
||||
<include path="fess.xml"/>
|
||||
<include path="fess_ldap.xml"/>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</component>
|
||||
<component name="pathMappingHelper" class="org.codelibs.fess.helper.PathMappingHelper">
|
||||
</component>
|
||||
<component name="jobHelper" class="org.codelibs.fess.helper.JobHelper">
|
||||
<component name="processHelper" class="org.codelibs.fess.helper.ProcessHelper">
|
||||
</component>
|
||||
<component name="sambaHelper" class="org.codelibs.fess.helper.SambaHelper">
|
||||
</component>
|
||||
|
|
|
@ -222,6 +222,8 @@ mail.from.address = root@localhost
|
|||
# Scheduler
|
||||
# ------
|
||||
scheduler.target.name=
|
||||
scheduler.job.class=org.codelibs.fess.app.job.ScriptExecutorJob
|
||||
scheduler.concurrent.exec.mode=QUIT
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# OnlineHelp
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"default_crawler"}}
|
||||
{"name":"Default Crawler","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"crawlJob\").logLevel(\"info\").execute(executor);","jobLogging":true,"crawler":true,"available":true,"sortOrder":1,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"name":"Default Crawler","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"crawlJob\").logLevel(\"info\").execute(executor);","jobLogging":true,"crawler":true,"available":true,"sortOrder":1,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"suggest_indexer"}}
|
||||
{"name":"Suggest Indexer","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"suggestJob\").logLevel(\"info\").sessionId(\"SUGGEST\").execute(executor);","jobLogging":true,"crawler":false,"available":true,"sortOrder":2,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"name":"Suggest Indexer","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"suggestJob\").logLevel(\"info\").sessionId(\"SUGGEST\").execute(executor);","jobLogging":true,"crawler":false,"available":true,"sortOrder":2,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"log_aggregator"}}
|
||||
{"name":"Log Aggregator","target":"all","cronExpression":"0 * * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"aggregateLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":3,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"name":"Log Aggregator","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"aggregateLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":3,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"log_purger"}}
|
||||
{"name":"Log Purger","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":4,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"name":"Log Purger","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":4,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"doc_purger"}}
|
||||
{"name":"Doc Purger","target":"all","cronExpression":"0 * * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeDocJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":5,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
{"name":"Doc Purger","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeDocJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":5,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
<!DOCTYPE components PUBLIC "-//DBFLUTE//DTD LastaDi 1.0//EN"
|
||||
"http://dbflute.org/meta/lastadi10.dtd">
|
||||
<components>
|
||||
<component name="jobScheduler" class="org.codelibs.fess.job.JobScheduler">
|
||||
</component>
|
||||
<component name="groovyJobExecutor" class="org.codelibs.fess.job.impl.GroovyExecutor" instance="prototype">
|
||||
</component>
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
org.quartz.scheduler.instanceName=JobScheduler
|
||||
org.quartz.threadPool.threadCount=5
|
||||
|
Loading…
Add table
Reference in a new issue