1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.server;
21
22 import org.waarp.common.database.exception.WaarpDatabaseException;
23 import org.waarp.common.logging.WaarpLogger;
24 import org.waarp.common.logging.WaarpLoggerFactory;
25 import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
26 import org.waarp.common.utility.ParametersChecker;
27 import org.waarp.common.utility.WaarpStringUtils;
28 import org.waarp.openr66.client.AbstractTransfer;
29 import org.waarp.openr66.client.DirectTransfer;
30 import org.waarp.openr66.configuration.FileBasedConfiguration;
31 import org.waarp.openr66.context.ErrorCode;
32 import org.waarp.openr66.context.R66FiniteDualStates;
33 import org.waarp.openr66.context.R66Result;
34 import org.waarp.openr66.database.data.DbHostAuth;
35 import org.waarp.openr66.database.data.DbTaskRunner;
36 import org.waarp.openr66.protocol.configuration.Configuration;
37 import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessException;
38 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoDataException;
39 import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
40 import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
41 import org.waarp.openr66.protocol.localhandler.packet.JsonCommandPacket;
42 import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
43 import org.waarp.openr66.protocol.localhandler.packet.json.LogJsonPacket;
44 import org.waarp.openr66.protocol.localhandler.packet.json.LogResponseJsonPacket;
45 import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
46 import org.waarp.openr66.protocol.utils.ChannelUtils;
47 import org.waarp.openr66.protocol.utils.R66Future;
48
49 import java.io.File;
50 import java.sql.Timestamp;
51
52 import static org.waarp.common.database.DbConstant.*;
53
54
55
56
57 public class LogExtendedExport implements Runnable {
58
59
60
61 static volatile WaarpLogger logger;
62
63 protected static final String INFO_ARGS =
64 "Need at least the configuration file as first argument then optionally\n" +
65 " -purge\n -clean\n -startid id\n -stopid id\n -rule rule\n -request host\n" +
66 " -pending\n -transfer\n -done\n -error\n" +
67 " -start timestamp in format yyyyMMddHHmmssSSS possibly truncated and where one of ':-. ' can be separators\n" +
68 " -stop timestamp in same format than start\n" +
69 "If not start and no stop are given, stop is Today Midnight (00:00:00)\n" +
70 "If start is equals or greater than stop, stop is start+24H\n" +
71 " -host host (optional additional options:\n" +
72 " -ruleDownload ruleDownload if set, will try to download the exported logs\n" +
73 " -import that will try to import exported logs using ruleDownload to download the logs)";
74
75 protected final R66Future future;
76 protected final boolean clean;
77 protected final boolean purgeLog;
78 protected final Timestamp start;
79 protected final Timestamp stop;
80 protected final String startid;
81 protected final String stopid;
82 protected final String rule;
83 protected final String request;
84 protected final boolean statuspending;
85 protected final boolean statustransfer;
86 protected final boolean statusdone;
87 protected final boolean statuserror;
88 protected String ruleDownload;
89 protected boolean tryimport;
90 protected final NetworkTransaction networkTransaction;
91 protected DbHostAuth host;
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public LogExtendedExport(final R66Future future, final boolean clean,
111 final boolean purgeLog, final Timestamp start,
112 final Timestamp stop, final String startid,
113 final String stopid, final String rule,
114 final String request, final boolean statuspending,
115 final boolean statustransfer,
116 final boolean statusdone, final boolean statuserror,
117 final NetworkTransaction networkTransaction,
118 final DbHostAuth host) {
119 this.future = future;
120 this.clean = clean;
121 this.purgeLog = purgeLog;
122 this.start = start;
123 this.stop = stop;
124 this.startid = startid;
125 this.stopid = stopid;
126 this.rule = rule;
127 this.request = request;
128 this.statuspending = statuspending;
129 this.statustransfer = statustransfer;
130 this.statusdone = statusdone;
131 this.statuserror = statuserror;
132 this.networkTransaction = networkTransaction;
133 this.host = host;
134 if (logger == null) {
135 logger = WaarpLoggerFactory.getLogger(LogExtendedExport.class);
136 }
137 }
138
139
140
141
142
143
144
145
146 public void setDownloadTryImport(final String ruleDownload,
147 final boolean tryimport) {
148 this.ruleDownload = ruleDownload;
149 this.tryimport = ruleDownload != null && tryimport && !host.getHostid()
150 .equals(
151 Configuration.configuration.getHostId()) &&
152 !host.getHostid()
153 .equals(Configuration.configuration.getHostSslId());
154 }
155
156
157
158
159
160
161 @Override
162 public void run() {
163 if (logger == null) {
164 logger = WaarpLoggerFactory.getLogger(LogExtendedExport.class);
165 }
166 if (!(statusdone || statuserror || statuspending || statustransfer)) {
167 logger.error("No action required");
168 future.setResult(new R66Result(
169 new OpenR66ProtocolNoDataException("No action required"), null, true,
170 ErrorCode.IncorrectCommand, null));
171 future.setFailure(future.getResult().getException());
172 return;
173 }
174
175 final byte type = purgeLog? LocalPacketFactory.LOGPURGEPACKET :
176 LocalPacketFactory.LOGPACKET;
177 final LogJsonPacket node = new LogJsonPacket();
178 node.setClean(clean);
179 node.setPurge(purgeLog);
180 node.setStart(start);
181 node.setStop(stop);
182 node.setStartid(startid);
183 node.setStopid(stopid);
184 node.setRule(rule);
185 node.setRequest(request);
186 node.setStatuspending(statuspending);
187 node.setStatustransfer(statustransfer);
188 node.setStatuserror(statuserror);
189 node.setStatusdone(statusdone);
190
191 final JsonCommandPacket valid = new JsonCommandPacket(node, type);
192 logger.debug("ExtendedLogCommand: {}", valid.getRequest());
193 final R66Future newFuture = new R66Future(true);
194 final LocalChannelReference localChannelReference =
195 AbstractTransfer.tryConnect(host, newFuture, networkTransaction);
196 if (localChannelReference == null) {
197 future.setResult(newFuture.getResult());
198 future.setFailure(future.getCause());
199 return;
200 }
201 localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
202 try {
203 ChannelUtils.writeAbstractLocalPacket(localChannelReference, valid, true);
204 } catch (final OpenR66ProtocolPacketException e) {
205 logger.error("Bad Protocol", e);
206 localChannelReference.close();
207 host = null;
208 future.setResult(
209 new R66Result(e, null, true, ErrorCode.TransferError, null));
210 future.setFailure(e);
211 return;
212 }
213 host = null;
214 newFuture.awaitOrInterruptible();
215 logger.info("Request done with {}",
216 newFuture.isSuccess()? "success" : "error");
217 if (newFuture.isSuccess() && ParametersChecker.isNotEmpty(ruleDownload)) {
218 try {
219 importLog(newFuture);
220 } catch (final OpenR66ProtocolBusinessException e) {
221 localChannelReference.close();
222 return;
223 }
224 }
225 future.setFilesize(newFuture.getFilesize());
226 future.setRunner(newFuture.getRunner());
227 future.setResult(newFuture.getResult());
228 if (newFuture.isSuccess()) {
229 future.setSuccess();
230 } else {
231 if (newFuture.getCause() != null) {
232 future.setFailure(newFuture.getCause());
233 }
234 future.cancel();
235 }
236 localChannelReference.close();
237 }
238
239 public void importLog(final R66Future future)
240 throws OpenR66ProtocolBusinessException {
241 if (future.isSuccess()) {
242 final JsonCommandPacket packet =
243 (JsonCommandPacket) future.getResult().getOther();
244 if (packet != null) {
245 final LogResponseJsonPacket res =
246 (LogResponseJsonPacket) packet.getJsonRequest();
247 final String fileExported = res.getFilename();
248
249 if (ParametersChecker.isNotEmpty(fileExported)) {
250 final String ruleToExport = ruleDownload;
251 final R66Future futuretemp = new R66Future(true);
252 final DirectTransfer transfer =
253 new DirectTransfer(futuretemp, host.getHostid(), fileExported,
254 ruleToExport, "Get Exported Logs from " +
255 Configuration.configuration.getHostId(),
256 false,
257 Configuration.configuration.getBlockSize(),
258 ILLEGALVALUE, networkTransaction);
259 transfer.run();
260 final File logsFile;
261 if (!futuretemp.isSuccess()) {
262 if (futuretemp.getCause() != null) {
263 throw new OpenR66ProtocolBusinessException(futuretemp.getCause());
264 }
265 throw new OpenR66ProtocolBusinessException(
266 "Download of exported logs in error");
267 } else {
268 logsFile = futuretemp.getResult().getFile().getTrueFile();
269 }
270 if (tryimport) {
271 try {
272 DbTaskRunner.loadXml(logsFile);
273 } catch (final OpenR66ProtocolBusinessException e) {
274 logger.warn(
275 "Cannot load the logs from " + logsFile.getAbsolutePath() +
276 " since: " + e.getMessage());
277 throw new OpenR66ProtocolBusinessException(
278 "Cannot load the logs from " + logsFile.getAbsolutePath(), e);
279 }
280 }
281 } else {
282 throw new OpenR66ProtocolBusinessException(
283 "Export log with no file result");
284 }
285 } else {
286 throw new OpenR66ProtocolBusinessException(
287 "Export log with no file result");
288 }
289 } else {
290 if (future.getCause() != null) {
291 throw new OpenR66ProtocolBusinessException(future.getCause());
292 }
293 throw new OpenR66ProtocolBusinessException("Export log in error");
294 }
295 }
296
297 protected static boolean sclean;
298 protected static boolean spurgeLog;
299 protected static Timestamp sstart;
300 protected static Timestamp sstop;
301 protected static String sstartid;
302 protected static String sstopid;
303 protected static String srule;
304 protected static String srequest;
305 protected static boolean sstatuspending;
306 protected static boolean sstatustransfer;
307 protected static boolean sstatusdone = true;
308 protected static boolean sstatuserror;
309 protected static String stohost;
310 protected static String sruleDownload;
311 protected static boolean stryimport;
312
313 protected static boolean getParams(final String[] args) {
314 if (logger == null) {
315 logger = WaarpLoggerFactory.getLogger(LogExtendedExport.class);
316 }
317 if (args.length < 1) {
318 logger.error(INFO_ARGS);
319 return false;
320 }
321 if (!FileBasedConfiguration.setClientConfigurationFromXml(
322 Configuration.configuration, args[0])) {
323 logger.error(INFO_ARGS);
324 return false;
325 }
326 String ssstart = null;
327 String ssstop = null;
328 for (int i = 1; i < args.length; i++) {
329 if ("-purge".equalsIgnoreCase(args[i])) {
330 spurgeLog = true;
331 } else if ("-clean".equalsIgnoreCase(args[i])) {
332 sclean = true;
333 } else if ("-start".equalsIgnoreCase(args[i])) {
334 i++;
335 ssstart = args[i];
336 } else if ("-stop".equalsIgnoreCase(args[i])) {
337 i++;
338 ssstop = args[i];
339 } else if ("-startid".equalsIgnoreCase(args[i])) {
340 i++;
341 sstartid = args[i];
342 } else if ("-stopid".equalsIgnoreCase(args[i])) {
343 i++;
344 sstopid = args[i];
345 } else if ("-rule".equalsIgnoreCase(args[i])) {
346 i++;
347 srule = args[i];
348 } else if ("-request".equalsIgnoreCase(args[i])) {
349 i++;
350 srequest = args[i];
351 } else if ("-pending".equalsIgnoreCase(args[i])) {
352 sstatuspending = true;
353 } else if ("-transfer".equalsIgnoreCase(args[i])) {
354 sstatustransfer = true;
355 } else if ("-done".equalsIgnoreCase(args[i])) {
356 sstatusdone = true;
357 } else if ("-error".equalsIgnoreCase(args[i])) {
358 sstatuserror = true;
359 } else if ("-import".equalsIgnoreCase(args[i])) {
360 stryimport = true;
361 } else if ("-host".equalsIgnoreCase(args[i])) {
362 i++;
363 stohost = args[i];
364 } else if ("-ruleDownload".equalsIgnoreCase(args[i])) {
365 i++;
366 sruleDownload = args[i];
367 }
368 }
369 if (ssstart != null) {
370 final Timestamp tstart = WaarpStringUtils.fixDate(ssstart);
371 if (tstart != null) {
372 sstart = tstart;
373 }
374 }
375 if (ssstop != null) {
376 final Timestamp tstop = WaarpStringUtils.fixDate(ssstop, sstart);
377 if (tstop != null) {
378 sstop = tstop;
379 }
380 }
381 if (ssstart == null && ssstop == null) {
382 sstop = WaarpStringUtils.getTodayMidnight();
383 }
384 if (stohost == null) {
385 stryimport = false;
386 }
387 return true;
388 }
389
390 public static void main(final String[] args) {
391 WaarpLoggerFactory.setDefaultFactoryIfNotSame(
392 new WaarpSlf4JLoggerFactory(null));
393 if (logger == null) {
394 logger = WaarpLoggerFactory.getLogger(LogExtendedExport.class);
395 }
396 if (!getParams(args)) {
397 logger.error("Wrong initialization");
398 if (admin != null) {
399 admin.close();
400 }
401 System.exit(1);
402 }
403 final long time1 = System.currentTimeMillis();
404 DbHostAuth dbhost = null;
405 if (stohost != null) {
406 try {
407 dbhost = new DbHostAuth(stohost);
408 } catch (final WaarpDatabaseException e) {
409 logger.error("Wrong initialization");
410 if (admin != null) {
411 admin.close();
412 }
413 System.exit(2);
414 }
415 } else {
416 dbhost = Configuration.configuration.getHostSslAuth();
417 stohost = Configuration.configuration.getHostSslId();
418 }
419 final R66Future future = new R66Future(true);
420
421 Configuration.configuration.pipelineInit();
422 final NetworkTransaction networkTransaction = new NetworkTransaction();
423 try {
424 final LogExtendedExport transaction =
425 new LogExtendedExport(future, sclean, spurgeLog, sstart, sstop,
426 sstartid, sstopid, srule, srequest,
427 sstatuspending, sstatustransfer, sstatusdone,
428 sstatuserror, networkTransaction, dbhost);
429 transaction.setDownloadTryImport(sruleDownload, stryimport);
430 transaction.run();
431 future.awaitOrInterruptible();
432 final long time2 = System.currentTimeMillis();
433 final long delay = time2 - time1;
434 final R66Result result = future.getResult();
435 if (future.isSuccess()) {
436 if (result.getCode() == ErrorCode.Warning) {
437 logger.warn("WARNED on file: " + (result.getOther() != null?
438 ((JsonCommandPacket) result.getOther()).getRequest() :
439 "no file") + " delay: " + delay);
440 } else {
441 logger.warn("SUCCESS on Final file: " +
442 (result.getOther() != null?
443 ((JsonCommandPacket) result.getOther()).getRequest() :
444 "no file") + " delay: " + delay);
445 }
446 } else {
447 if (result.getCode() == ErrorCode.Warning) {
448 logger.warn("LogExtendedExport is WARNED" + " : {}",
449 future.getCause() != null?
450 future.getCause().getMessage() : "");
451 } else {
452 logger.error("LogExtendedExport in FAILURE" + " : {}",
453 future.getCause() != null?
454 future.getCause().getMessage() : "");
455 }
456 networkTransaction.closeAll();
457 System.exit(result.getCode().ordinal());
458 }
459 } finally {
460 networkTransaction.closeAll();
461 System.exit(0);
462 }
463 }
464
465 }