1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package openr66.server;
22
23 import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
24 import goldengate.common.logging.GgInternalLogger;
25 import goldengate.common.logging.GgInternalLoggerFactory;
26 import goldengate.common.logging.GgSlf4JLoggerFactory;
27
28 import java.net.SocketAddress;
29 import java.sql.Timestamp;
30 import java.text.ParseException;
31 import java.text.SimpleDateFormat;
32 import java.util.Date;
33 import java.util.GregorianCalendar;
34
35 import openr66.configuration.FileBasedConfiguration;
36 import openr66.context.ErrorCode;
37 import openr66.context.R66FiniteDualStates;
38 import openr66.context.R66Result;
39 import openr66.database.DbConstant;
40 import openr66.database.data.DbHostAuth;
41 import openr66.database.data.DbTaskRunner;
42 import openr66.protocol.configuration.Configuration;
43 import openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
44 import openr66.protocol.exception.OpenR66ProtocolPacketException;
45 import openr66.protocol.localhandler.LocalChannelReference;
46 import openr66.protocol.localhandler.packet.LocalPacketFactory;
47 import openr66.protocol.localhandler.packet.ValidPacket;
48 import openr66.protocol.networkhandler.NetworkTransaction;
49 import openr66.protocol.utils.ChannelUtils;
50 import openr66.protocol.utils.R66Future;
51
52 import org.jboss.netty.channel.Channels;
53 import org.jboss.netty.logging.InternalLoggerFactory;
54
55
56
57
58
59
60
61 public class LogExport implements Runnable {
62
63
64
65 static volatile GgInternalLogger logger;
66
67 protected final R66Future future;
68 protected final boolean purgeLog;
69 protected final Timestamp start;
70 protected final Timestamp stop;
71 protected final boolean clean;
72 protected final NetworkTransaction networkTransaction;
73
74 public LogExport(R66Future future, boolean purgeLog, boolean clean,
75 Timestamp start, Timestamp stop,
76 NetworkTransaction networkTransaction) {
77 this.future = future;
78 this.purgeLog = purgeLog;
79 this.clean = clean;
80 this.start = start;
81 this.stop = stop;
82 this.networkTransaction = networkTransaction;
83 }
84
85
86
87
88 public void run() {
89 if (logger == null) {
90 logger = GgInternalLoggerFactory.getLogger(LogExport.class);
91 }
92 String lstart = (start != null) ? start.toString() : null;
93 String lstop = (stop != null) ? stop.toString() : null;
94 byte type = (purgeLog) ? LocalPacketFactory.LOGPURGEPACKET : LocalPacketFactory.LOGPACKET;
95 ValidPacket valid = new ValidPacket(lstart, lstop, type);
96 DbHostAuth host = Configuration.configuration.HOST_SSLAUTH;
97 SocketAddress socketAddress = host.getSocketAddress();
98 boolean isSSL = host.isSsl();
99
100
101 if (clean) {
102
103
104 try {
105 DbTaskRunner.changeFinishedToDone(DbConstant.admin.session);
106 } catch (GoldenGateDatabaseNoConnectionException e) {
107 logger.warn("Clean cannot be done {}", e.getMessage());
108 }
109 }
110 LocalChannelReference localChannelReference = networkTransaction
111 .createConnectionWithRetry(socketAddress, isSSL, future);
112 socketAddress = null;
113 if (localChannelReference == null) {
114 host = null;
115 logger.error("Cannot Connect");
116 future.setResult(new R66Result(
117 new OpenR66ProtocolNoConnectionException("Cannot connect to server"),
118 null, true, ErrorCode.Internal, null));
119 future.setFailure(future.getResult().exception);
120 return;
121 }
122 localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
123 try {
124 ChannelUtils.writeAbstractLocalPacket(localChannelReference, valid, false);
125 } catch (OpenR66ProtocolPacketException e) {
126 logger.error("Bad Protocol", e);
127 Channels.close(localChannelReference.getLocalChannel());
128 localChannelReference = null;
129 host = null;
130 valid = null;
131 future.setResult(new R66Result(e, null, true,
132 ErrorCode.TransferError, null));
133 future.setFailure(e);
134 return;
135 }
136 host = null;
137 future.awaitUninterruptibly();
138 logger.info("Request done with "+(future.isSuccess()?"success":"error"));
139 Channels.close(localChannelReference.getLocalChannel());
140 localChannelReference = null;
141 }
142
143 protected static boolean spurgeLog = false;
144 protected static Timestamp sstart = null;
145 protected static Timestamp sstop = null;
146 protected static boolean sclean = false;
147
148 private static SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
149 private static Timestamp fixDate(String sdate) {
150 Timestamp tdate = null;
151 String date = sdate.replaceAll("/|:|\\.| |-", "");
152 if (date.length() > 0) {
153 if (date.length() < 15) {
154 int len = date.length();
155 date += "000000000000000".substring(len);
156 }
157 try {
158 Date ddate = format.parse(date);
159 tdate = new Timestamp(ddate.getTime());
160 } catch (ParseException e) {
161 logger.debug("start {}",e.getMessage());
162 }
163 }
164 return tdate;
165 }
166 private static Timestamp fixDate(String sdate, Timestamp before) {
167 Timestamp tdate = null;
168 String date = sdate.replaceAll("/|:|\\.| |-", "");
169 if (date.length() > 0) {
170 if (date.length() < 15) {
171 int len = date.length();
172 date += "000000000000000".substring(len);
173 }
174 try {
175 Date ddate = format.parse(date);
176 if (before != null) {
177 Date bef = new Date(before.getTime());
178 if (bef.compareTo(ddate) >= 0) {
179 ddate = new Date(bef.getTime()+1000*3600*24-1);
180 }
181 }
182 tdate = new Timestamp(ddate.getTime());
183 } catch (ParseException e) {
184 logger.debug("start {}",e.getMessage());
185 }
186 }
187 return tdate;
188 }
189 private static Timestamp getTodayMidnight() {
190 GregorianCalendar calendar = new GregorianCalendar();
191 calendar.set(GregorianCalendar.HOUR_OF_DAY, 0);
192 calendar.set(GregorianCalendar.MINUTE, 0);
193 calendar.set(GregorianCalendar.SECOND, 0);
194 calendar.set(GregorianCalendar.MILLISECOND, 0);
195 return new Timestamp(calendar.getTimeInMillis());
196 }
197 protected static boolean getParams(String [] args) {
198 if (args.length < 1) {
199 logger.error("Need at least the configuration file as first argument then optionally\n" +
200 " -purge\n" +
201 " -clean\n" +
202 " -start timestamp in format yyyyMMddHHmmssSSS possibly truncated and where one of ':-. ' can be separators\n" +
203 " -stop timestamp in same format than start\n" +
204 "If not start and no stop are given, stop is Today Midnight (00:00:00)\n" +
205 "If start is equals or greater than stop, stop is start+24H");
206 return false;
207 }
208 if (! FileBasedConfiguration
209 .setClientConfigurationFromXml(Configuration.configuration, args[0])) {
210 logger.error("Need at least the configuration file as first argument then optionally\n" +
211 " -purge\n" +
212 " -clean\n" +
213 " -start timestamp in format yyyyMMddHHmmssSSS possibly truncated and where one of ':-. ' can be separators\n" +
214 " -stop timestamp in same format than start\n" +
215 "If not start and no stop are given, stop is Today Midnight (00:00:00)\n" +
216 "If start is equals or greater than stop, stop is start+24H");
217 return false;
218 }
219 String ssstart = null;
220 String ssstop = null;
221 for (int i = 1; i < args.length; i++) {
222 if (args[i].equalsIgnoreCase("-purge")) {
223 spurgeLog = true;
224 } else if (args[i].equalsIgnoreCase("-clean")) {
225 sclean = true;
226 } else if (args[i].equalsIgnoreCase("-start")) {
227 i++;
228 ssstart = args[i];
229 } else if (args[i].equalsIgnoreCase("-stop")) {
230 i++;
231 ssstop = args[i];
232 }
233 }
234 if (ssstart != null) {
235 Timestamp tstart = fixDate(ssstart);
236 if (tstart != null) {
237 sstart = tstart;
238 }
239 }
240 if (ssstop != null) {
241 Timestamp tstop = fixDate(ssstop, sstart);
242 if (tstop != null) {
243 sstop = tstop;
244 }
245 }
246 if (ssstart == null && ssstop == null) {
247 sstop = getTodayMidnight();
248 }
249 return true;
250 }
251
252 public static void main(String[] args) {
253 InternalLoggerFactory.setDefaultFactory(new GgSlf4JLoggerFactory(null));
254 if (logger == null) {
255 logger = GgInternalLoggerFactory.getLogger(LogExport.class);
256 }
257 if (! getParams(args)) {
258 logger.error("Wrong initialization");
259 if (DbConstant.admin != null && DbConstant.admin.isConnected) {
260 DbConstant.admin.close();
261 }
262 System.exit(1);
263 }
264 long time1 = System.currentTimeMillis();
265 R66Future future = new R66Future(true);
266
267 Configuration.configuration.pipelineInit();
268 NetworkTransaction networkTransaction = new NetworkTransaction();
269 try {
270 LogExport transaction = new LogExport(future,
271 spurgeLog, sclean, sstart, sstop,
272 networkTransaction);
273 transaction.run();
274 future.awaitUninterruptibly();
275 long time2 = System.currentTimeMillis();
276 long delay = time2 - time1;
277 R66Result result = future.getResult();
278 if (future.isSuccess()) {
279 if (result.code == ErrorCode.Warning) {
280 logger.warn("WARNED on file:\n " +
281 (result.other != null? ((ValidPacket)result.other).getSheader() :
282 "no file")
283 +"\n delay: "+delay);
284 } else {
285 logger.warn("SUCCESS on Final file:\n " +
286 (result.other != null? ((ValidPacket)result.other).getSheader() :
287 "no file")
288 +"\n delay: "+delay);
289 }
290 } else {
291 if (result.code == ErrorCode.Warning) {
292 logger.warn("Transfer is\n WARNED", future.getCause());
293 networkTransaction.closeAll();
294 System.exit(result.code.ordinal());
295 } else {
296 logger.error("Transfer in\n FAILURE", future.getCause());
297 networkTransaction.closeAll();
298 System.exit(result.code.ordinal());
299 }
300 }
301 } finally {
302 networkTransaction.closeAll();
303 }
304 }
305
306 }