View Javadoc
1   /*
2    * Copyright 2012-2021 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
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; // sec
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 }