1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.job;
17
18 import java.io.File;
19 import java.io.FileOutputStream;
20 import java.io.FilenameFilter;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Properties;
26
27 import org.apache.commons.io.FileUtils;
28 import org.apache.logging.log4j.LogManager;
29 import org.apache.logging.log4j.Logger;
30 import org.codelibs.core.timer.TimeoutManager;
31 import org.codelibs.core.timer.TimeoutTask;
32 import org.codelibs.fess.Constants;
33 import org.codelibs.fess.es.config.exentity.ScheduledJob;
34 import org.codelibs.fess.util.ComponentUtil;
35 import org.lastaflute.di.exception.IORuntimeException;
36 import org.lastaflute.job.LaJobRuntime;
37
38 public abstract class ExecJob {
39
40 private static final Logger logger = LogManager.getLogger(ExecJob.class);
41
42 protected JobExecutor jobExecutor;
43
44 protected String sessionId;
45
46 protected boolean useLocalFesen = true;
47
48 protected String logFilePath;
49
50 protected String logLevel;
51
52 protected List<String> jvmOptions = new ArrayList<>();
53
54 protected String lastaEnv;
55
56 protected int timeout = -1;
57
58 protected boolean processTimeout = false;
59
60 public abstract String execute();
61
62 protected abstract String getExecuteType();
63
64 public String execute(final JobExecutor jobExecutor) {
65 jobExecutor(jobExecutor);
66 return execute();
67 }
68
69 public ExecJob jobExecutor(final JobExecutor jobExecutor) {
70 this.jobExecutor = jobExecutor;
71 return this;
72 }
73
74 public ExecJob sessionId(final String sessionId) {
75 this.sessionId = sessionId;
76 return this;
77 }
78
79 public ExecJob logFilePath(final String logFilePath) {
80 this.logFilePath = logFilePath;
81 return this;
82 }
83
84 public ExecJob logLevel(final String logLevel) {
85 this.logLevel = logLevel;
86 return this;
87 }
88
89 public ExecJob timeout(final int timeout) {
90 this.timeout = timeout;
91 return this;
92 }
93
94 public ExecJob useLocalFesen(final boolean useLocalFesen) {
95 this.useLocalFesen = useLocalFesen;
96 return this;
97 }
98
99 public ExecJob remoteDebug() {
100 return jvmOptions("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=localhost:8000");
101 }
102
103 public ExecJob gcLogging() {
104 final StringBuilder buf = new StringBuilder(100);
105 buf.append("-Xlog:gc*,gc+age=trace,safepoint:file=");
106 if (logFilePath != null) {
107 buf.append(logFilePath);
108 } else {
109 buf.append(ComponentUtil.getSystemHelper().getLogFilePath());
110 }
111 buf.append(File.separator);
112 buf.append("gc-").append(getExecuteType()).append(".log");
113 buf.append(":utctime,pid,tags:filecount=5,filesize=64m");
114 return jvmOptions(buf.toString());
115 }
116
117 public ExecJob jvmOptions(final String... options) {
118 Collections.addAll(this.jvmOptions, options);
119 return this;
120 }
121
122 public ExecJob lastaEnv(final String env) {
123 this.lastaEnv = env;
124 return this;
125 }
126
127 protected void addSystemProperty(final List<String> cmdList, final String name, final String defaultValue, final String appendValue) {
128 final String value = System.getProperty(name);
129 if (value != null) {
130 final StringBuilder buf = new StringBuilder();
131 buf.append("-D").append(name).append("=").append(value);
132 if (appendValue != null) {
133 buf.append(appendValue);
134 }
135 cmdList.add(buf.toString());
136 } else if (defaultValue != null) {
137 cmdList.add("-D" + name + "=" + defaultValue);
138 }
139 }
140
141 protected void addFessConfigProperties(final List<String> cmdList) {
142 System.getProperties().keySet().stream().filter(k -> k != null && k.toString().startsWith(Constants.FESS_CONFIG_PREFIX))
143 .forEach(k -> addSystemProperty(cmdList, k.toString(), null, null));
144 }
145
146 protected void addFessSystemProperties(final List<String> cmdList) {
147 System.getProperties().keySet().stream().filter(k -> k != null && k.toString().startsWith(Constants.SYSTEM_PROP_PREFIX))
148 .forEach(k -> addSystemProperty(cmdList, k.toString(), null, null));
149 }
150
151 protected void deleteTempDir(final File ownTmpDir) {
152 if (ownTmpDir == null) {
153 return;
154 }
155 if (!FileUtils.deleteQuietly(ownTmpDir)) {
156 logger.warn("Could not delete a temp dir: {}", ownTmpDir.getAbsolutePath());
157 }
158 }
159
160 protected void appendJarFile(final String cpSeparator, final StringBuilder buf, final File libDir, final String basePath) {
161 final File[] jarFiles = libDir.listFiles((FilenameFilter) (dir, name) -> name.toLowerCase().endsWith(".jar"));
162 if (jarFiles != null) {
163 for (final File file : jarFiles) {
164 buf.append(cpSeparator);
165 buf.append(basePath);
166 buf.append(file.getName());
167 }
168 }
169 }
170
171 protected TimeoutTask createTimeoutTask() {
172 if (timeout <= 0) {
173 return null;
174 }
175 return TimeoutManager.getInstance().addTimeoutTarget(() -> {
176 logger.warn("Process is terminated due to {} second exceeded.", timeout);
177 ComponentUtil.getProcessHelper().destroyProcess(sessionId);
178 processTimeout = true;
179 }, timeout, false);
180 }
181
182 protected void createSystemProperties(final List<String> cmdList, final File propFile) {
183 try (FileOutputStream out = new FileOutputStream(propFile)) {
184 final Properties prop = new Properties();
185 prop.putAll(ComponentUtil.getSystemProperties());
186 final LaJobRuntime jobRuntime = ComponentUtil.getJobHelper().getJobRuntime();
187 if (jobRuntime != null) {
188 final ScheduledJob job = (ScheduledJob) jobRuntime.getParameterMap().get(Constants.SCHEDULED_JOB);
189 if (job != null) {
190 prop.setProperty("job.runtime.id", job.getId());
191 prop.setProperty("job.runtime.name", job.getName());
192 }
193 }
194 prop.store(out, cmdList.toString());
195 } catch (final IOException e) {
196 throw new IORuntimeException(e);
197 }
198 }
199 }