Project

General

Profile

1 522 berkley
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements replication for metacat
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Chad Berkley
7
 *
8
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11 669 jones
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25 522 berkley
 */
26
27 5014 daigle
package edu.ucsb.nceas.metacat.replication;
28 522 berkley
29 5755 leinfelder
import java.io.BufferedInputStream;
30
import java.io.BufferedOutputStream;
31 6102 leinfelder
import java.io.ByteArrayInputStream;
32
import java.io.ByteArrayOutputStream;
33 5755 leinfelder
import java.io.File;
34
import java.io.FileInputStream;
35
import java.io.FileNotFoundException;
36
import java.io.FileOutputStream;
37
import java.io.IOException;
38
import java.io.InputStream;
39
import java.io.InputStreamReader;
40
import java.io.OutputStream;
41
import java.io.StringReader;
42
import java.io.Writer;
43
import java.net.MalformedURLException;
44
import java.net.URL;
45
import java.sql.PreparedStatement;
46
import java.sql.ResultSet;
47
import java.sql.SQLException;
48
import java.text.SimpleDateFormat;
49 2572 tao
import java.util.Date;
50 5895 berkley
import java.util.Enumeration;
51 5755 leinfelder
import java.util.Hashtable;
52 6118 leinfelder
import java.util.List;
53 5755 leinfelder
import java.util.Timer;
54
import java.util.Vector;
55 4080 daigle
56 5755 leinfelder
import javax.servlet.http.HttpServletRequest;
57
import javax.servlet.http.HttpServletResponse;
58 574 berkley
59 5755 leinfelder
import org.apache.log4j.Logger;
60 6366 leinfelder
import org.dataone.service.types.v1.SystemMetadata;
61 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
62 5755 leinfelder
import org.xml.sax.InputSource;
63
import org.xml.sax.SAXException;
64
import org.xml.sax.XMLReader;
65
66 5014 daigle
import edu.ucsb.nceas.metacat.DocInfoHandler;
67
import edu.ucsb.nceas.metacat.DocumentImpl;
68
import edu.ucsb.nceas.metacat.DocumentImplWrapper;
69
import edu.ucsb.nceas.metacat.EventLog;
70 5755 leinfelder
import edu.ucsb.nceas.metacat.IdentifierManager;
71
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
72 5014 daigle
import edu.ucsb.nceas.metacat.McdbException;
73 5195 daigle
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlException;
74 5089 daigle
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile;
75 5195 daigle
import edu.ucsb.nceas.metacat.accesscontrol.PermOrderException;
76 5098 daigle
import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessDAO;
77 6001 cjones
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException;
78 5014 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
79
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
80
import edu.ucsb.nceas.metacat.database.DatabaseService;
81 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
82 5014 daigle
import edu.ucsb.nceas.metacat.shared.BaseService;
83
import edu.ucsb.nceas.metacat.shared.HandlerException;
84
import edu.ucsb.nceas.metacat.shared.ServiceException;
85 5027 daigle
import edu.ucsb.nceas.metacat.util.DocumentUtil;
86 4698 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
87 6102 leinfelder
import edu.ucsb.nceas.metacat.util.ReplicationUtil;
88 4080 daigle
import edu.ucsb.nceas.metacat.util.SystemUtil;
89 4488 daigle
import edu.ucsb.nceas.utilities.FileUtil;
90 4087 daigle
import edu.ucsb.nceas.utilities.GeneralPropertyException;
91 4080 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
92
93 5014 daigle
public class ReplicationService extends BaseService {
94 4335 daigle
95 5014 daigle
	private static ReplicationService replicationService = null;
96 2663 sgarg
97 5014 daigle
	private long timeInterval;
98
	private Date firstTime;
99
	private boolean timedReplicationIsOn = false;
100
	Timer replicationDaemon;
101
	private static Vector<String> fileLocks = new Vector<String>();
102
//	private Thread lockThread = null;
103
	public static final String FORCEREPLICATEDELETE = "forcereplicatedelete";
104
	private static String TIMEREPLICATION = "replication.timedreplication";
105
	private static String TIMEREPLICATIONINTERVAl ="replication.timedreplicationinterval";
106
	private static String FIRSTTIME = "replication.firsttimedreplication";
107
	private static final int TIMEINTERVALLIMIT = 7200000;
108
	public static final String REPLICATIONUSER = "replication";
109 2286 tao
110 5014 daigle
	public static final String REPLICATION_LOG_FILE_NAME = "metacatreplication.log";
111
	public static String METACAT_REPL_ERROR_MSG = null;
112
	private static Logger logReplication = Logger.getLogger("ReplicationLogging");
113
	private static Logger logMetacat = Logger.getLogger(ReplicationService.class);
114 2286 tao
115 5014 daigle
	private ReplicationService() throws ServiceException {
116
		_serviceName = "ReplicationService";
117
118
		initialize();
119
	}
120
121
	private void initialize() throws ServiceException {
122
123
		// initialize db connections to handle any update requests
124
		// deltaT = util.getProperty("replication.deltaT");
125
		// the default deltaT can be set from metacat.properties
126
		// create a thread to do the delta-T check but don't execute it yet
127
		replicationDaemon = new Timer(true);
128
		try {
129
			String replLogFile = PropertyService.getProperty("replication.logdir")
130
				+ FileUtil.getFS() + REPLICATION_LOG_FILE_NAME;
131
			METACAT_REPL_ERROR_MSG = "An error occurred in replication.  Please see the " +
132
				"replication log at: " + replLogFile;
133
134
			String timedRepIsOnStr =
135
				PropertyService.getProperty("replication.timedreplication");
136
			timedReplicationIsOn = (new Boolean(timedRepIsOnStr)).booleanValue();
137
			logReplication.info("ReplicationService.initialize - The timed replication on is" + timedReplicationIsOn);
138 522 berkley
139 5014 daigle
			String timeIntervalStr =
140
				PropertyService.getProperty("replication.timedreplicationinterval");
141
			timeInterval = (new Long(timeIntervalStr)).longValue();
142
			logReplication.info("ReplicationService.initialize - The timed replication time Interval is " + timeInterval);
143 2286 tao
144 5014 daigle
			String firstTimeStr =
145
				PropertyService.getProperty("replication.firsttimedreplication");
146
			logReplication.info("ReplicationService.initialize - first replication time form property is " + firstTimeStr);
147
			firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
148 2286 tao
149 5014 daigle
			logReplication.info("ReplicationService.initialize - After combine current time, the real first time is "
150
					+ firstTime.toString() + " minisec");
151 2286 tao
152 5014 daigle
			// set up time replication if it is on
153
			if (timedReplicationIsOn) {
154
				replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(),
155
						firstTime, timeInterval);
156
				logReplication.info("ReplicationService.initialize - deltaT handler started with rate="
157
						+ timeInterval + " mini seconds at " + firstTime.toString());
158
			}
159 2286 tao
160 5014 daigle
		} catch (PropertyNotFoundException pnfe) {
161
			throw new ServiceException(
162
					"ReplicationService.initialize - Property error while instantiating "
163
							+ "replication service: " + pnfe.getMessage());
164
		} catch (HandlerException he) {
165
			throw new ServiceException(
166
					"ReplicationService.initialize - Handler error while instantiating "
167
							+ "replication service" + he.getMessage());
168
		}
169
	}
170 2286 tao
171 5014 daigle
	/**
172
	 * Get the single instance of SessionService.
173
	 *
174
	 * @return the single instance of SessionService
175
	 */
176
	public static ReplicationService getInstance() throws ServiceException {
177
		if (replicationService == null) {
178
			replicationService = new ReplicationService();
179
		}
180
		return replicationService;
181
	}
182 2286 tao
183 5014 daigle
	public boolean refreshable() {
184
		return true;
185
	}
186 2286 tao
187 5014 daigle
	protected void doRefresh() throws ServiceException {
188
		return;
189
	}
190
191
	public void stop() throws ServiceException{
192
193
	}
194 840 bojilova
195 5014 daigle
	public void stopReplication() throws ServiceException {
196
	      //stop the replication server
197
	      replicationDaemon.cancel();
198
	      replicationDaemon = new Timer(true);
199
	      timedReplicationIsOn = false;
200
	      try {
201
	    	  PropertyService.setProperty("replication.timedreplication", (new Boolean(timedReplicationIsOn)).toString());
202
	      } catch (GeneralPropertyException gpe) {
203
	    	  logReplication.warn("ReplicationService.stopReplication - Could not set replication.timedreplication property: " + gpe.getMessage());
204
	      }
205 4080 daigle
206 5014 daigle
	      logReplication.info("ReplicationService.stopReplication - deltaT handler stopped");
207
		return;
208
	}
209
210
	protected void startReplication(Hashtable<String, String[]> params) throws ServiceException {
211 2286 tao
212 5014 daigle
	       String firstTimeStr = "";
213
	      //start the replication server
214
	       if ( params.containsKey("rate") ) {
215
	        timeInterval = new Long(
216
	               new String(((String[])params.get("rate"))[0])).longValue();
217
	        if(timeInterval < TIMEINTERVALLIMIT) {
218
	            //deltaT<30 is a timing mess!
219
	            timeInterval = TIMEINTERVALLIMIT;
220
	            throw new ServiceException("Replication deltaT rate cannot be less than "+
221
	                    TIMEINTERVALLIMIT + " millisecs and system automatically setup the rate to "+TIMEINTERVALLIMIT);
222
	        }
223
	      } else {
224
	        timeInterval = TIMEINTERVALLIMIT ;
225
	      }
226
	      logReplication.info("ReplicationService.startReplication - New rate is: " + timeInterval + " mini seconds.");
227
	      if ( params.containsKey("firsttime"))
228
	      {
229
	         firstTimeStr = ((String[])params.get("firsttime"))[0];
230
	         try
231
	         {
232
	           firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
233
	           logReplication.info("ReplicationService.startReplication - The first time setting is "+firstTime.toString());
234
	         }
235
	         catch (HandlerException e)
236
	         {
237
	            throw new ServiceException(e.getMessage());
238
	         }
239
	         logReplication.warn("After combine current time, the real first time is "
240
	                                  +firstTime.toString()+" minisec");
241
	      }
242
	      else
243
	      {
244
	    	  logMetacat.error("ReplicationService.startReplication - " + ReplicationService.METACAT_REPL_ERROR_MSG);
245
	          logReplication.error("ReplicationService.startReplication - You should specify the first time " +
246
	                                  "to start a time replication");
247
	          return;
248
	      }
249
250
	      timedReplicationIsOn = true;
251
	      try {
252
	      // save settings to property file
253
	      PropertyService.setProperty(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
254
	      // note we couldn't use firstTime object because it has date info
255
	      // we only need time info such as 10:00 PM
256
	      PropertyService.setProperty(FIRSTTIME, firstTimeStr);
257
	      PropertyService.setProperty(TIMEREPLICATIONINTERVAl, (new Long(timeInterval)).toString());
258
	      } catch (GeneralPropertyException gpe) {
259
	    	  logReplication.warn("ReplicationService.startReplication - Could not set property: " + gpe.getMessage());
260
	      }
261
	      replicationDaemon.cancel();
262
	      replicationDaemon = new Timer(true);
263
	      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime,
264
	                                            timeInterval);
265
266
	      logReplication.info("ReplicationService.startReplication - deltaT handler started with rate=" +
267
	                                    timeInterval + " milliseconds at " +firstTime.toString());
268 837 bojilova
269 5014 daigle
	}
270
271
	public void runOnce() throws ServiceException {
272
	      //updates this server exactly once
273
	      replicationDaemon.schedule(new ReplicationHandler(), 0);
274
	}
275 2286 tao
276 5014 daigle
	/**
277
	 * This method can add, delete and list the servers currently included in
278
	 * xml_replication.
279
	 * action           subaction            other needed params
280
	 * ---------------------------------------------------------
281
	 * servercontrol    add                  server
282
	 * servercontrol    delete               server
283
	 * servercontrol    list
284
	 */
285 5755 leinfelder
	protected static void handleServerControlRequest(
286 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
287
		String subaction = ((String[]) params.get("subaction"))[0];
288
		DBConnection dbConn = null;
289
		int serialNumber = -1;
290
		PreparedStatement pstmt = null;
291
		String replicate = null;
292
		String server = null;
293
		String dataReplicate = null;
294 6135 leinfelder
		String systemMetadataReplicate = null;
295 5014 daigle
		String hub = null;
296 5755 leinfelder
		Writer out = null;
297 5014 daigle
		try {
298 5755 leinfelder
			response.setContentType("text/xml");
299
			out = response.getWriter();
300
301 5014 daigle
			//conn = util.openDBConnection();
302
			dbConn = DBConnectionPool
303
					.getDBConnection("MetacatReplication.handleServerControlRequest");
304
			serialNumber = dbConn.getCheckOutSerialNumber();
305 837 bojilova
306 5014 daigle
			// add server to server list
307
			if (subaction.equals("add")) {
308
				replicate = ((String[]) params.get("replicate"))[0];
309
				server = ((String[]) params.get("server"))[0];
310 2286 tao
311 5014 daigle
				//Get data replication value
312
				dataReplicate = ((String[]) params.get("datareplicate"))[0];
313 6135 leinfelder
				//Get system metadata replication value
314
				systemMetadataReplicate = ((String[]) params.get("systemmetadatareplicate"))[0];
315 5014 daigle
				//Get hub value
316
				hub = ((String[]) params.get("hub"))[0];
317 837 bojilova
318 5319 jones
				String toDateSql = DatabaseService.getInstance().getDBAdapter().toDate("01/01/1980","MM/DD/YYYY");
319 5151 daigle
				String sql = "INSERT INTO xml_replication "
320 6135 leinfelder
						+ "(server, last_checked, replicate, datareplicate, systemmetadatareplicate, hub) "
321
						+ "VALUES (?," + toDateSql + ",?,?,?,?)";
322 5151 daigle
323
				pstmt = dbConn.prepareStatement(sql);
324
325
				pstmt.setString(1, server);
326
				pstmt.setInt(2, Integer.parseInt(replicate));
327
				pstmt.setInt(3, Integer.parseInt(dataReplicate));
328 6135 leinfelder
				pstmt.setInt(4, Integer.parseInt(systemMetadataReplicate));
329
				pstmt.setInt(5, Integer.parseInt(hub));
330 5151 daigle
331
				String sqlReport = "XMLAccessAccess.getXMLAccessForDoc - SQL: " + sql;
332
				sqlReport += " [" + server + "," + replicate +
333
					"," + dataReplicate + "," + hub + "]";
334
335
				logMetacat.info(sqlReport);
336
337 5014 daigle
				pstmt.execute();
338
				pstmt.close();
339
				dbConn.commit();
340 5755 leinfelder
				out.write("Server " + server + " added");
341 5014 daigle
				response.setContentType("text/html");
342 5755 leinfelder
				out.write("<html><body><table border=\"1\">");
343 6135 leinfelder
				out.write("<tr><td><b>server</b></td>");
344
				out.write("<td><b>last_checked</b></td>");
345
				out.write("<td><b>replicate</b></td>");
346 5755 leinfelder
				out.write("<td><b>datareplicate</b></td>");
347 6135 leinfelder
				out.write("<td><b>systemmetadatareplicate</b></td>");
348 5755 leinfelder
				out.write("<td><b>hub</b></td></tr>");
349 6135 leinfelder
				pstmt = dbConn.prepareStatement("SELECT serverid, server, last_checked, replicate, datareplicate, systemmetadatareplicate, hub FROM xml_replication");
350 5014 daigle
				//increase dbconnection usage
351
				dbConn.increaseUsageCount(1);
352 2298 tao
353 5014 daigle
				pstmt.execute();
354
				ResultSet rs = pstmt.getResultSet();
355
				boolean tablehasrows = rs.next();
356
				while (tablehasrows) {
357 5755 leinfelder
					out.write("<tr><td>" + rs.getString(2) + "</td><td>");
358
					out.write(rs.getString(3) + "</td><td>");
359
					out.write(rs.getString(4) + "</td><td>");
360
					out.write(rs.getString(5) + "</td><td>");
361 6135 leinfelder
					out.write(rs.getString(6) + "</td><td>");
362
					out.write(rs.getString(7) + "</td></tr>");
363 837 bojilova
364 5014 daigle
					tablehasrows = rs.next();
365
				}
366 5755 leinfelder
				out.write("</table></body></html>");
367 837 bojilova
368 5014 daigle
				// download certificate with the public key on this server
369
				// and import it as a trusted certificate
370
				String certURL = ((String[]) params.get("certificate"))[0];
371 5151 daigle
				if (certURL != null && !certURL.equals("")) {
372
					downloadCertificate(certURL);
373
				}
374 837 bojilova
375 5014 daigle
				// delete server from server list
376
			} else if (subaction.equals("delete")) {
377
				server = ((String[]) params.get("server"))[0];
378
				pstmt = dbConn.prepareStatement("DELETE FROM xml_replication "
379
						+ "WHERE server LIKE '" + server + "'");
380
				pstmt.execute();
381
				pstmt.close();
382
				dbConn.commit();
383 5755 leinfelder
				out.write("Server " + server + " deleted");
384 5014 daigle
				response.setContentType("text/html");
385 5755 leinfelder
				out.write("<html><body><table border=\"1\">");
386 6135 leinfelder
				out.write("<tr><td><b>server</b></td>");
387
				out.write("<td><b>last_checked</b></td>");
388
				out.write("<td><b>replicate</b></td>");
389 5755 leinfelder
				out.write("<td><b>datareplicate</b></td>");
390 6135 leinfelder
				out.write("<td><b>systemmetadatareplicate</b></td>");
391 5755 leinfelder
				out.write("<td><b>hub</b></td></tr>");
392 837 bojilova
393 6135 leinfelder
				pstmt = dbConn.prepareStatement("SELECT serverid, server, last_checked, replicate, datareplicate, systemmetadatareplicate, hub FROM xml_replication");
394 5014 daigle
				//increase dbconnection usage
395
				dbConn.increaseUsageCount(1);
396
				pstmt.execute();
397
				ResultSet rs = pstmt.getResultSet();
398
				boolean tablehasrows = rs.next();
399
				while (tablehasrows) {
400 5755 leinfelder
					out.write("<tr><td>" + rs.getString(2) + "</td><td>");
401
					out.write(rs.getString(3) + "</td><td>");
402
					out.write(rs.getString(4) + "</td><td>");
403
					out.write(rs.getString(5) + "</td><td>");
404 6135 leinfelder
					out.write(rs.getString(6) + "</td><td>");
405
					out.write(rs.getString(7) + "</td></tr>");
406 5014 daigle
					tablehasrows = rs.next();
407
				}
408 5755 leinfelder
				out.write("</table></body></html>");
409 837 bojilova
410 5014 daigle
				// list servers in server list
411
			} else if (subaction.equals("list")) {
412
				response.setContentType("text/html");
413 5755 leinfelder
				out.write("<html><body><table border=\"1\">");
414 6135 leinfelder
				out.write("<tr><td><b>server</b></td>");
415
				out.write("<td><b>last_checked</b></td>");
416
				out.write("<td><b>replicate</b></td>");
417 5755 leinfelder
				out.write("<td><b>datareplicate</b></td>");
418 6135 leinfelder
				out.write("<td><b>systemmetadatareplicate</b></td>");
419 5755 leinfelder
				out.write("<td><b>hub</b></td></tr>");
420 6135 leinfelder
				pstmt = dbConn.prepareStatement("SELECT serverid, server, last_checked, replicate, datareplicate, systemmetadatareplicate, hub FROM xml_replication");
421 5014 daigle
				pstmt.execute();
422
				ResultSet rs = pstmt.getResultSet();
423
				boolean tablehasrows = rs.next();
424
				while (tablehasrows) {
425 5755 leinfelder
					out.write("<tr><td>" + rs.getString(2) + "</td><td>");
426
					out.write(rs.getString(3) + "</td><td>");
427
					out.write(rs.getString(4) + "</td><td>");
428
					out.write(rs.getString(5) + "</td><td>");
429 6135 leinfelder
					out.write(rs.getString(6) + "</td><td>");
430
					out.write(rs.getString(7) + "</td></tr>");
431
432 5014 daigle
					tablehasrows = rs.next();
433
				}
434 5755 leinfelder
				out.write("</table></body></html>");
435 5014 daigle
			} else {
436 2286 tao
437 5755 leinfelder
				out.write("<error>Unkonwn subaction</error>");
438 2286 tao
439 5014 daigle
			}
440
			pstmt.close();
441
			//conn.close();
442 2286 tao
443 5014 daigle
		} catch (Exception e) {
444
			logMetacat.error("ReplicationService.handleServerControlRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
445
			logReplication.error("ReplicationService.handleServerControlRequest - Error in "
446
					+ "MetacatReplication.handleServerControlRequest " + e.getMessage());
447
			e.printStackTrace(System.out);
448
		} finally {
449
			try {
450
				pstmt.close();
451
			}//try
452
			catch (SQLException ee) {
453
				logMetacat.error("ReplicationService.handleServerControlRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
454
				logReplication.error("ReplicationService.handleServerControlRequest - Error in MetacatReplication.handleServerControlRequest to close pstmt "
455
						+ ee.getMessage());
456
			}//catch
457
			finally {
458
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
459
			}//finally
460 5755 leinfelder
			if (out != null) {
461
				try {
462
					out.close();
463
				} catch (IOException e) {
464
					logMetacat.error(e.getMessage(), e);
465
				}
466
			}
467 5014 daigle
		}//finally
468 2286 tao
469 5014 daigle
	}
470 2286 tao
471 5014 daigle
	// download certificate with the public key from certURL and
472 4080 daigle
	// upload it onto this server; it then must be imported as a
473
	// trusted certificate
474 5014 daigle
	private static void downloadCertificate(String certURL) throws FileNotFoundException,
475 4080 daigle
			IOException, MalformedURLException, PropertyNotFoundException {
476 5014 daigle
477 4080 daigle
		// the path to be uploaded to
478 5014 daigle
		String certPath = SystemUtil.getContextDir();
479 2286 tao
480 4080 daigle
		// get filename from the URL of the certificate
481
		String filename = certURL;
482
		int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
483
		if (slash > -1) {
484
			filename = filename.substring(slash + 1);
485
		}
486 2286 tao
487 4080 daigle
		// open file output strem to write the input into it
488
		File f = new File(certPath, filename);
489
		synchronized (f) {
490
			try {
491
				if (f.exists()) {
492
					throw new IOException("File already exist: " + f.getCanonicalFile());
493
					// if ( f.exists() && !f.canWrite() ) {
494
					// throw new IOException("Not writable: " +
495
					// f.getCanonicalFile());
496
				}
497
			} catch (SecurityException se) {
498
				// if a security manager exists,
499
				// its checkRead method is called for f.exist()
500
				// or checkWrite method is called for f.canWrite()
501
				throw se;
502
			}
503 2286 tao
504 4080 daigle
			// create a buffered byte output stream
505
			// that uses a default-sized output buffer
506
			FileOutputStream fos = new FileOutputStream(f);
507
			BufferedOutputStream out = new BufferedOutputStream(fos);
508 840 bojilova
509 4080 daigle
			// this should be http url
510
			URL url = new URL(certURL);
511
			BufferedInputStream bis = null;
512
			try {
513
				bis = new BufferedInputStream(url.openStream());
514
				byte[] buf = new byte[4 * 1024]; // 4K buffer
515
				int b = bis.read(buf);
516
				while (b != -1) {
517
					out.write(buf, 0, b);
518
					b = bis.read(buf);
519
				}
520
			} finally {
521
				if (bis != null)
522
					bis.close();
523
			}
524
			// the input and the output streams must be closed
525
			bis.close();
526
			out.flush();
527
			out.close();
528
			fos.close();
529
		} // end of synchronized(f)
530
	}
531 2286 tao
532 5014 daigle
	/**
533 4080 daigle
	 * when a forcereplication request comes in, local host sends a read request
534
	 * to the requesting server (remote server) for the specified docid. Then
535
	 * store it in local database.
536
	 */
537 5755 leinfelder
	protected static void handleForceReplicateRequest(
538 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
539
			HttpServletRequest request) {
540
		String server = ((String[]) params.get("server"))[0]; // the server that
541
		String docid = ((String[]) params.get("docid"))[0]; // sent the document
542
		String dbaction = "UPDATE"; // the default action is UPDATE
543
		//    boolean override = false;
544
		//    int serverCode = 1;
545
		DBConnection dbConn = null;
546
		int serialNumber = -1;
547 5459 berkley
		String docName = null;
548 2286 tao
549 5014 daigle
		try {
550
			//if the url contains a dbaction then the default action is overridden
551
			if (params.containsKey("dbaction")) {
552
				dbaction = ((String[]) params.get("dbaction"))[0];
553
				//serverCode = MetacatReplication.getServerCode(server);
554
				//override = true; //we are now overriding the default action
555
			}
556
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication request from: " + server);
557
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication docid: " + docid);
558
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication action: " + dbaction);
559
			// sending back read request to remote server
560
			URL u = new URL("https://" + server + "?server="
561
					+ MetacatUtil.getLocalReplicationServerName() + "&action=read&docid="
562
					+ docid);
563
			String xmldoc = ReplicationService.getURLContent(u);
564 2286 tao
565 5014 daigle
			// get the document info from server
566
			URL docinfourl = new URL("https://" + server + "?server="
567
					+ MetacatUtil.getLocalReplicationServerName()
568
					+ "&action=getdocumentinfo&docid=" + docid);
569 5440 berkley
570 2286 tao
571 5014 daigle
			String docInfoStr = ReplicationService.getURLContent(docinfourl);
572 6102 leinfelder
			// strip out the system metadata portion
573
			String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
574
			docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
575
576 5014 daigle
			//dih is the parser for the docinfo xml format
577
			DocInfoHandler dih = new DocInfoHandler();
578
			XMLReader docinfoParser = ReplicationHandler.initParser(dih);
579
			docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
580
			//      Hashtable<String,Vector<AccessControlForSingleFile>> docinfoHash = dih.getDocInfo();
581
			Hashtable<String, String> docinfoHash = dih.getDocInfo();
582 6015 leinfelder
583 5014 daigle
			// Get home server of this docid
584
			String homeServer = (String) docinfoHash.get("home_server");
585 5324 berkley
586 6102 leinfelder
			// process system metadata
587
			if (systemMetadataXML != null) {
588
				SystemMetadata sysMeta =
589 6367 leinfelder
					TypeMarshaller.unmarshalTypeFromStream(
590 6102 leinfelder
							SystemMetadata.class,
591
							new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
592
				String guid = sysMeta.getIdentifier().getValue();
593
				if (!IdentifierManager.getInstance().identifierExists(guid)) {
594
					logReplication.debug("Creating system metadata and guid/docid mapping for docid "
595
									+ docinfoHash.get("docid")
596
									+ " and guid: "
597
									+ guid);
598
					IdentifierManager.getInstance().createMapping(guid, docinfoHash.get("docid"));
599
					IdentifierManager.getInstance().createSystemMetadata(sysMeta);
600
				} else {
601
					logReplication.debug("Updating guid/docid mapping for docid "
602
									+ docinfoHash.get("docid") + " and guid: "
603
									+ guid);
604
					IdentifierManager.getInstance().updateMapping(guid, docinfoHash.get("docid"));
605
				}
606
				IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
607 6099 leinfelder
			}
608 5324 berkley
609 6099 leinfelder
        	// replicate doc contents
610 5014 daigle
			String createdDate = (String) docinfoHash.get("date_created");
611
			String updatedDate = (String) docinfoHash.get("date_updated");
612
			logReplication.info("ReplicationService.handleForceReplicateRequest - homeServer: " + homeServer);
613
			// Get Document type
614
			String docType = (String) docinfoHash.get("doctype");
615
			logReplication.info("ReplicationService.handleForceReplicateRequest - docType: " + docType);
616
			String parserBase = null;
617
			// this for eml2 and we need user eml2 parser
618
			if (docType != null
619
					&& (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE)) {
620
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml200 document!");
621
				parserBase = DocumentImpl.EML200;
622
			} else if (docType != null
623
					&& (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE)) {
624
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.0.1 document!");
625
				parserBase = DocumentImpl.EML200;
626
			} else if (docType != null
627
					&& (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE)) {
628
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.1.0 document!");
629
				parserBase = DocumentImpl.EML210;
630 5709 leinfelder
			} else if (docType != null
631
					&& (docType.trim()).equals(DocumentImpl.EML2_1_1NAMESPACE)) {
632
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.1.1 document!");
633
				parserBase = DocumentImpl.EML210;
634 5014 daigle
			}
635
			logReplication.warn("ReplicationService.handleForceReplicateRequest - The parserBase is: " + parserBase);
636 2286 tao
637 5014 daigle
			// Get DBConnection from pool
638
			dbConn = DBConnectionPool
639
					.getDBConnection("MetacatReplication.handleForceReplicateRequest");
640
			serialNumber = dbConn.getCheckOutSerialNumber();
641
			// write the document to local database
642
			DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false);
643 6079 leinfelder
			//try this independently so we can set access even if the update action is invalid (i.e docid has not changed)
644 5014 daigle
			try {
645 5195 daigle
				wrapper.writeReplication(dbConn, xmldoc, null, null,
646 6015 leinfelder
						dbaction, docid, null, null, homeServer, server, createdDate,
647 5014 daigle
						updatedDate);
648 5195 daigle
			} finally {
649 3230 tao
650 5195 daigle
				//process extra access rules before dealing with the write exception (doc exist already)
651
		        Vector<XMLAccessDAO> accessControlList = dih.getAccessControlList();
652
		        if (accessControlList != null) {
653
		        	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
654
		        	for (XMLAccessDAO xmlAccessDAO : accessControlList) {
655
		        		if (!acfsf.accessControlExists(xmlAccessDAO)) {
656
		        			acfsf.insertPermissions(xmlAccessDAO);
657
							logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid
658
									+ " permissions added to DB");
659
		        		}
660
		            }
661
		        }
662 6015 leinfelder
663
		        // process the real owner and updater
664
				String user = (String) docinfoHash.get("user_owner");
665
				String updated = (String) docinfoHash.get("user_updated");
666
		        updateUserOwner(dbConn, docid, user, updated);
667 2286 tao
668 5195 daigle
				logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid + " added to DB with "
669
						+ "action " + dbaction);
670 5458 berkley
671 6079 leinfelder
				EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
672 5014 daigle
			}
673 5195 daigle
		} catch (SQLException sqle) {
674 5014 daigle
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
675 5195 daigle
			logReplication.error("ReplicationService.handleForceReplicateRequest - SQL error when adding doc " + docid +
676
					" to DB with action " + dbaction + ": " + sqle.getMessage());
677
		} catch (MalformedURLException mue) {
678
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
679
			logReplication.error("ReplicationService.handleForceReplicateRequest - URL error when adding doc " + docid +
680
					" to DB with action " + dbaction + ": " + mue.getMessage());
681
		} catch (SAXException se) {
682
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
683
			logReplication.error("ReplicationService.handleForceReplicateRequest - SAX parsing error when adding doc " + docid +
684
					" to DB with action " + dbaction + ": " + se.getMessage());
685
		} catch (HandlerException he) {
686
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
687
			logReplication.error("ReplicationService.handleForceReplicateRequest - Handler error when adding doc " + docid +
688
					" to DB with action " + dbaction + ": " + he.getMessage());
689
		} catch (IOException ioe) {
690
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
691
			logReplication.error("ReplicationService.handleForceReplicateRequest - I/O error when adding doc " + docid +
692
					" to DB with action " + dbaction + ": " + ioe.getMessage());
693
		} catch (PermOrderException poe) {
694
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
695
			logReplication.error("ReplicationService.handleForceReplicateRequest - Permissions order error when adding doc " + docid +
696
					" to DB with action " + dbaction + ": " + poe.getMessage());
697
		} catch (AccessControlException ace) {
698
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
699
			logReplication.error("ReplicationService.handleForceReplicateRequest - Permissions order error when adding doc " + docid +
700
					" to DB with action " + dbaction + ": " + ace.getMessage());
701
		} catch (Exception e) {
702
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
703
			logReplication.error("ReplicationService.handleForceReplicateRequest - General error when adding doc " + docid +
704
					" to DB with action " + dbaction + ": " + e.getMessage());
705
		} finally {
706 5014 daigle
			// Return the checked out DBConnection
707
			DBConnectionPool.returnDBConnection(dbConn, serialNumber);
708
		}//finally
709
	}
710 2298 tao
711 5014 daigle
	/*
712
	 * when a forcereplication delete request comes in, local host will delete this
713
	 * document
714
	 */
715 5755 leinfelder
	protected static void handleForceReplicateDeleteRequest(
716 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
717
			HttpServletRequest request) {
718
		String server = ((String[]) params.get("server"))[0]; // the server that
719
		String docid = ((String[]) params.get("docid"))[0]; // sent the document
720
		try {
721
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - force replication delete request from " + server);
722
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - force replication delete docid " + docid);
723
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - Force replication delete request from: " + server);
724
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - Force replication delete docid: " + docid);
725
			DocumentImpl.delete(docid, null, null, server);
726
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - document " + docid + " was successfully deleted ");
727
			EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid,
728
					"delete");
729
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - document " + docid + " was successfully deleted ");
730 6001 cjones
		} catch (McdbDocNotFoundException e) {
731
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
732
			logReplication.error("document " + docid
733
					+ " failed to delete because " + e.getMessage());
734
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
735
		} catch (InsufficientKarmaException e) {
736
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
737
			logReplication.error("document " + docid
738
					+ " failed to delete because " + e.getMessage());
739
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
740
		} catch (SQLException e) {
741
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
742
			logReplication.error("document " + docid
743
					+ " failed to delete because " + e.getMessage());
744
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
745 5014 daigle
		} catch (Exception e) {
746
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
747
			logReplication.error("document " + docid
748
					+ " failed to delete because " + e.getMessage());
749
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
750 2298 tao
751 5014 daigle
		}//catch
752 2298 tao
753 5014 daigle
	}
754 2286 tao
755 5014 daigle
	/**
756
	 * when a forcereplication data file request comes in, local host sends a
757
	 * readdata request to the requesting server (remote server) for the specified
758
	 * docid. Then store it in local database and file system
759
	 */
760
	protected static void handleForceReplicateDataFileRequest(Hashtable<String, String[]> params,
761
			HttpServletRequest request) {
762 2286 tao
763 5014 daigle
		//make sure there is some parameters
764
		if (params.isEmpty()) {
765
			return;
766
		}
767
		// Get remote server
768
		String server = ((String[]) params.get("server"))[0];
769
		// the docid should include rev number
770
		String docid = ((String[]) params.get("docid"))[0];
771
		// Make sure there is a docid and server
772
		if (docid == null || server == null || server.equals("")) {
773
			logMetacat.error("ReplicationService.handleForceReplicateDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
774
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - Didn't specify docid or server for replication");
775
			return;
776
		}
777 2286 tao
778 5014 daigle
		// Overide or not
779
		//    boolean override = false;
780
		// dbaction - update or insert
781
		String dbaction = null;
782 2286 tao
783 5014 daigle
		try {
784
			//docid was switch to two parts uinque code and rev
785
			//String uniqueCode=MetacatUtil.getDocIdFromString(docid);
786
			//int rev=MetacatUtil.getVersionFromString(docid);
787
			if (params.containsKey("dbaction")) {
788
				dbaction = ((String[]) params.get("dbaction"))[0];
789
			} else//default value is update
790
			{
791
				dbaction = "update";
792
			}
793 2286 tao
794 5014 daigle
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication request from: " + server);
795
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication docid: " + docid);
796
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication action: " + dbaction);
797
			// get the document info from server
798
			URL docinfourl = new URL("https://" + server + "?server="
799
					+ MetacatUtil.getLocalReplicationServerName()
800
					+ "&action=getdocumentinfo&docid=" + docid);
801 1023 tao
802 5014 daigle
			String docInfoStr = ReplicationService.getURLContent(docinfourl);
803 6102 leinfelder
804
			// strip out the system metadata portion
805
		    String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
806
		   	docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
807 2286 tao
808 5014 daigle
			//dih is the parser for the docinfo xml format
809
			DocInfoHandler dih = new DocInfoHandler();
810
			XMLReader docinfoParser = ReplicationHandler.initParser(dih);
811
			docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
812
			Hashtable<String, String> docinfoHash = dih.getDocInfo();
813 6015 leinfelder
814 5014 daigle
			String docName = (String) docinfoHash.get("docname");
815 2286 tao
816 5014 daigle
			String docType = (String) docinfoHash.get("doctype");
817 2286 tao
818 5014 daigle
			String docHomeServer = (String) docinfoHash.get("home_server");
819 2286 tao
820 5014 daigle
			String createdDate = (String) docinfoHash.get("date_created");
821 2286 tao
822 5014 daigle
			String updatedDate = (String) docinfoHash.get("date_updated");
823
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - docHomeServer of datafile: " + docHomeServer);
824
825
			if (dbaction.equals("insert") || dbaction.equals("update")) {
826
				//Get data file and store it into local file system.
827
				// sending back readdata request to server
828
				URL url = new URL("https://" + server + "?server="
829
						+ MetacatUtil.getLocalReplicationServerName()
830
						+ "&action=readdata&docid=" + docid);
831
				String datafilePath = PropertyService
832
						.getProperty("application.datafilepath");
833
834
				Exception writeException = null;
835
				//register data file into xml_documents table and wite data file
836
				//into file system
837
				try {
838
					DocumentImpl.writeDataFileInReplication(url.openStream(),
839 6015 leinfelder
							datafilePath, docName, docType, docid, null, docHomeServer,
840 5014 daigle
							server, DocumentImpl.DOCUMENTTABLE, false, createdDate,
841
							updatedDate);
842
				} catch (Exception e) {
843
					writeException = e;
844
				}
845 5098 daigle
846 6015 leinfelder
				// process the real owner and updater
847
				DBConnection dbConn = DBConnectionPool.getDBConnection("ReplicationService.handleForceDataFileRequest");
848
		        int serialNumber = dbConn.getCheckOutSerialNumber();
849
		        dbConn.setAutoCommit(false);
850
				String user = (String) docinfoHash.get("user_owner");
851
				String updated = (String) docinfoHash.get("user_updated");
852
		        updateUserOwner(dbConn, docid, user, updated);
853
		        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
854
855 5098 daigle
		        Vector<XMLAccessDAO> accessControlList = dih.getAccessControlList();
856
		        if (accessControlList != null) {
857
		        	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
858
		        	for (XMLAccessDAO xmlAccessDAO : accessControlList) {
859
		        		if (!acfsf.accessControlExists(xmlAccessDAO)) {
860
		        			acfsf.insertPermissions(xmlAccessDAO);
861
							logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid
862 5014 daigle
									+ " permissions added to DB");
863 5098 daigle
		        		}
864
		            }
865
		        }
866 6099 leinfelder
867 6102 leinfelder
		        // process system metadata
868
		        if (systemMetadataXML != null) {
869
		      	  SystemMetadata sysMeta =
870 6367 leinfelder
		      		TypeMarshaller.unmarshalTypeFromStream(
871 6102 leinfelder
		      				  SystemMetadata.class,
872
		      				  new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
873
		      	  String guid = sysMeta.getIdentifier().getValue();
874
		      	  if (!IdentifierManager.getInstance().identifierExists(guid)) {
875
		      		  logReplication.debug("Creating system metadata and guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
876
		      		  IdentifierManager.getInstance().createMapping(guid, docinfoHash.get("docid"));
877
		      		  IdentifierManager.getInstance().createSystemMetadata(sysMeta);
878
		      	  } else {
879
		      		  logReplication.debug("Updating guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
880
		      		  IdentifierManager.getInstance().updateMapping(guid, docinfoHash.get("docid"));
881
		      	  }
882
		      	  IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
883
		        }
884 5014 daigle
885
				if (writeException != null) {
886
					throw writeException;
887
				}
888
889
				logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - datafile " + docid + " added to DB with "
890
						+ "action " + dbaction);
891
				EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER,
892
						docid, dbaction);
893
			}
894
895
		} catch (Exception e) {
896
			logMetacat.error("ReplicationService.handleForceReplicateDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
897
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - Datafile " + docid
898
					+ " failed to added to DB with " + "action " + dbaction + " because "
899
					+ e.getMessage());
900
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - ERROR in MetacatReplication.handleForceDataFileReplicate"
901
					+ "Request(): " + e.getMessage());
902 4449 leinfelder
		}
903 5014 daigle
	}
904 2286 tao
905 5014 daigle
	/**
906
	 * Grants or denies a lock to a requesting host.
907
	 * The servlet parameters of interrest are:
908
	 * docid: the docid of the file the lock is being requested for
909
	 * currentdate: the timestamp of the document on the remote server
910
	 *
911
	 */
912 5755 leinfelder
	protected static void handleGetLockRequest(
913 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
914 1292 tao
915 5014 daigle
		try {
916 2286 tao
917 5014 daigle
			String docid = ((String[]) params.get("docid"))[0];
918
			String remoteRev = ((String[]) params.get("updaterev"))[0];
919
			DocumentImpl requestDoc = new DocumentImpl(docid);
920
			logReplication.info("ReplicationService.handleGetLockRequest - lock request for " + docid);
921
			int localRevInt = requestDoc.getRev();
922
			int remoteRevInt = Integer.parseInt(remoteRev);
923 2286 tao
924 5755 leinfelder
			// get a writer for sending back to response
925
			response.setContentType("text/xml");
926
			Writer out = response.getWriter();
927
928 5014 daigle
			if (remoteRevInt >= localRevInt) {
929
				if (!fileLocks.contains(docid)) { //grant the lock if it is not already locked
930
					fileLocks.add(0, docid); //insert at the beginning of the queue Vector
931
					//send a message back to the the remote host authorizing the insert
932 5755 leinfelder
					out.write("<lockgranted><docid>" + docid
933 5014 daigle
									+ "</docid></lockgranted>");
934
					//          lockThread = new Thread(this);
935
					//          lockThread.setPriority(Thread.MIN_PRIORITY);
936
					//          lockThread.start();
937
					logReplication.info("ReplicationService.handleGetLockRequest - lock granted for " + docid);
938
				} else { //deny the lock
939 5755 leinfelder
					out.write("<filelocked><docid>" + docid + "</docid></filelocked>");
940 5014 daigle
					logReplication.info("ReplicationService.handleGetLockRequest - lock denied for " + docid
941
							+ "reason: file already locked");
942
				}
943
			} else {//deny the lock.
944 5755 leinfelder
				out.write("<outdatedfile><docid>" + docid + "</docid></filelocked>");
945 5014 daigle
				logReplication.info("ReplicationService.handleGetLockRequest - lock denied for " + docid
946
						+ "reason: client has outdated file");
947
			}
948 5755 leinfelder
			out.close();
949 5014 daigle
			//conn.close();
950
		} catch (Exception e) {
951
			logMetacat.error("ReplicationService.handleGetLockRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
952
			logReplication.error("ReplicationService.handleGetLockRequest - error requesting file lock from MetacatReplication."
953
					+ "handleGetLockRequest: " + e.getMessage());
954
			e.printStackTrace(System.out);
955
		}
956
	}
957 2286 tao
958 5014 daigle
	/**
959
	 * Sends all of the xml_documents information encoded in xml to a requestor
960
	 * the format is:
961
	 * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
962
	 *                  user_updated, home_server, public_access, rev)/>
963
	 * all of the subelements of document info are #PCDATA
964
	 */
965 5755 leinfelder
	protected static void handleGetDocumentInfoRequest(
966 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
967
		String docid = ((String[]) (params.get("docid")))[0];
968
		StringBuffer sb = new StringBuffer();
969 2286 tao
970 5014 daigle
		try {
971
			DocumentImpl doc = new DocumentImpl(docid);
972
			sb.append("<documentinfo><docid>").append(docid);
973 5322 berkley
			sb.append("</docid>");
974 6102 leinfelder
975
			try {
976
				// serialize the System Metadata as XML for docinfo
977
				String guid = IdentifierManager.getInstance().getGUID(doc.getDocID(), doc.getRev());
978
				SystemMetadata systemMetadata = IdentifierManager.getInstance().getSystemMetadata(guid);
979
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
980 6367 leinfelder
				TypeMarshaller.marshalTypeToOutputStream(systemMetadata, baos);
981 6102 leinfelder
				String systemMetadataXML = baos.toString("UTF-8");
982
				sb.append("<systemMetadata>");
983
				sb.append(systemMetadataXML);
984
				sb.append("</systemMetadata>");
985
			} catch(McdbDocNotFoundException e) {
986
			  logMetacat.warn("No SystemMetadata found for: " + docid);
987 5322 berkley
			}
988
			sb.append("<docname>").append(doc.getDocname());
989 5014 daigle
			sb.append("</docname><doctype>").append(doc.getDoctype());
990
			sb.append("</doctype>");
991
			sb.append("<user_owner>").append(doc.getUserowner());
992
			sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
993
			sb.append("</user_updated>");
994
			sb.append("<date_created>");
995
			sb.append(doc.getCreateDate());
996
			sb.append("</date_created>");
997
			sb.append("<date_updated>");
998
			sb.append(doc.getUpdateDate());
999
			sb.append("</date_updated>");
1000
			sb.append("<home_server>");
1001
			sb.append(doc.getDocHomeServer());
1002
			sb.append("</home_server>");
1003
			sb.append("<public_access>").append(doc.getPublicaccess());
1004
			sb.append("</public_access><rev>").append(doc.getRev());
1005
			sb.append("</rev>");
1006 2286 tao
1007 5014 daigle
			sb.append("<accessControl>");
1008 5098 daigle
1009
			AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
1010
			sb.append(acfsf.getAccessString());
1011
1012 5014 daigle
			sb.append("</accessControl>");
1013 2286 tao
1014 5014 daigle
			sb.append("</documentinfo>");
1015 5755 leinfelder
			// get a writer for sending back to response
1016 5014 daigle
			response.setContentType("text/xml");
1017 5755 leinfelder
			Writer out = response.getWriter();
1018
			out.write(sb.toString());
1019
			out.close();
1020 2286 tao
1021 5014 daigle
		} catch (Exception e) {
1022
			logMetacat.error("ReplicationService.handleGetDocumentInfoRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1023
			logReplication.error("ReplicationService.handleGetDocumentInfoRequest - error in metacatReplication.handlegetdocumentinforequest "
1024
					+ "for doc: " + docid + " : " + e.getMessage());
1025
		}
1026 2286 tao
1027 5014 daigle
	}
1028 6118 leinfelder
1029
	/**
1030
	 * Sends System Metadata as XML
1031
	 */
1032
	protected static void handleGetSystemMetadataRequest(
1033
			Hashtable<String, String[]> params, HttpServletResponse response) {
1034
		String guid = ((String[]) (params.get("guid")))[0];
1035
		String systemMetadataXML = null;
1036
		try {
1037
1038
			// serialize the System Metadata as XML
1039
			SystemMetadata systemMetadata = IdentifierManager.getInstance().getSystemMetadata(guid);
1040
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
1041 6367 leinfelder
			TypeMarshaller.marshalTypeToOutputStream(systemMetadata, baos);
1042 6118 leinfelder
			systemMetadataXML = baos.toString("UTF-8");
1043
1044
			// get a writer for sending back to response
1045
			response.setContentType("text/xml");
1046
			Writer out = response.getWriter();
1047
			out.write(systemMetadataXML);
1048
			out.close();
1049 2286 tao
1050 6118 leinfelder
		} catch (Exception e) {
1051
			String msg = "ReplicationService.handleGetSystemMetadataRequest for guid: " + guid + " : " + e.getMessage();
1052
			logMetacat.error(msg);
1053
			logReplication.error(msg);
1054
		}
1055
1056
	}
1057 6119 leinfelder
1058
	/**
1059
	 * when a forcereplication request comes in, local host sends a read request
1060
	 * to the requesting server (remote server) for the specified docid. Then
1061
	 * store it in local database.
1062
	 */
1063
	protected static void handleForceReplicateSystemMetadataRequest(
1064
			Hashtable<String, String[]> params, HttpServletResponse response,
1065
			HttpServletRequest request) {
1066
		String server = ((String[]) params.get("server"))[0]; // the server that
1067
		String guid = ((String[]) params.get("guid"))[0]; // sent the document
1068
1069
		try {
1070
			logReplication.info("ReplicationService.handleForceReplicateSystemMetadataRequest - Force replication system metadata request from: " + server);
1071
			// get the system metadata from server
1072
			URL docinfourl = new URL("https://" + server + "?server="
1073
					+ MetacatUtil.getLocalReplicationServerName()
1074
					+ "&action=getsystemmetadata&guid=" + guid);
1075
1076
			String systemMetadataXML = ReplicationService.getURLContent(docinfourl);
1077
1078
			// process system metadata
1079
			if (systemMetadataXML != null) {
1080
				SystemMetadata sysMeta =
1081 6367 leinfelder
					TypeMarshaller.unmarshalTypeFromStream(
1082 6119 leinfelder
							SystemMetadata.class,
1083
							new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
1084
				if (!IdentifierManager.getInstance().identifierExists(guid)) {
1085
					logReplication.debug("Creating system metadata for guid: " + guid);
1086
					IdentifierManager.getInstance().createSystemMetadata(sysMeta);
1087
				}
1088
				IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
1089
			}
1090
1091
			logReplication.info("ReplicationService.handleForceReplicateSystemMetadataRequest - processed guid: " + guid);
1092
			EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, guid, "systemMetadata");
1093 6118 leinfelder
1094 6119 leinfelder
		} catch (Exception e) {
1095
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG, e);
1096
			logReplication.error("ReplicationService.handleForceReplicateRequest - General error when processing guid: " + guid, e);
1097
		}
1098
	}
1099
1100 5014 daigle
	/**
1101
	 * Sends a datafile to a remote host
1102
	 */
1103
	protected static void handleGetDataFileRequest(OutputStream outPut,
1104
			Hashtable<String, String[]> params, HttpServletResponse response)
1105 2286 tao
1106 5014 daigle
	{
1107
		// File path for data file
1108
		String filepath;
1109
		// Request docid
1110
		String docId = ((String[]) (params.get("docid")))[0];
1111
		//check if the doicd is null
1112
		if (docId == null) {
1113
			logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1114
			logReplication.error("ReplicationService.handleGetDataFileRequest - Didn't specify docid for replication");
1115
			return;
1116
		}
1117 2286 tao
1118 5014 daigle
		//try to open a https stream to test if the request server's public key
1119
		//in the key store, this is security issue
1120
		try {
1121
			filepath = PropertyService.getProperty("application.datafilepath");
1122
			String server = params.get("server")[0];
1123
			URL u = new URL("https://" + server + "?server="
1124
					+ MetacatUtil.getLocalReplicationServerName() + "&action=test");
1125
			String test = ReplicationService.getURLContent(u);
1126
			//couldn't pass the test
1127
			if (test.indexOf("successfully") == -1) {
1128
				//response.setContentType("text/xml");
1129
				//outPut.println("<error>Couldn't pass the trust test</error>");
1130
				logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1131
				logReplication.error("ReplicationService.handleGetDataFileRequest - Couldn't pass the trust test");
1132
				return;
1133
			}
1134
		}//try
1135
		catch (Exception ee) {
1136
			return;
1137
		}//catch
1138 2286 tao
1139 5014 daigle
		if (!filepath.endsWith("/")) {
1140
			filepath += "/";
1141
		}
1142
		// Get file aboslute file name
1143
		String filename = filepath + docId;
1144 2286 tao
1145 5014 daigle
		//MIME type
1146
		String contentType = null;
1147
		if (filename.endsWith(".xml")) {
1148
			contentType = "text/xml";
1149
		} else if (filename.endsWith(".css")) {
1150
			contentType = "text/css";
1151
		} else if (filename.endsWith(".dtd")) {
1152
			contentType = "text/plain";
1153
		} else if (filename.endsWith(".xsd")) {
1154
			contentType = "text/xml";
1155
		} else if (filename.endsWith("/")) {
1156
			contentType = "text/html";
1157
		} else {
1158
			File f = new File(filename);
1159
			if (f.isDirectory()) {
1160
				contentType = "text/html";
1161
			} else {
1162
				contentType = "application/octet-stream";
1163
			}
1164
		}
1165 2286 tao
1166 5014 daigle
		// Set the mime type
1167
		response.setContentType(contentType);
1168 2286 tao
1169 5014 daigle
		// Get the content of the file
1170
		FileInputStream fin = null;
1171
		try {
1172
			// FileInputStream to metacat
1173
			fin = new FileInputStream(filename);
1174
			// 4K buffer
1175
			byte[] buf = new byte[4 * 1024];
1176
			// Read data from file input stream to byte array
1177
			int b = fin.read(buf);
1178
			// Write to outStream from byte array
1179
			while (b != -1) {
1180
				outPut.write(buf, 0, b);
1181
				b = fin.read(buf);
1182
			}
1183
			// close file input stream
1184
			fin.close();
1185 2286 tao
1186 5014 daigle
		}//try
1187
		catch (Exception e) {
1188
			logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1189
			logReplication.error("ReplicationService.handleGetDataFileRequest - error getting data file from MetacatReplication."
1190
					+ "handlGetDataFileRequest " + e.getMessage());
1191
			e.printStackTrace(System.out);
1192
		}//catch
1193 2286 tao
1194 5014 daigle
	}
1195
1196
	/**
1197 4854 daigle
	 * Sends a document to a remote host
1198
	 */
1199 5755 leinfelder
	protected static void handleGetDocumentRequest(
1200 4854 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1201 2286 tao
1202 4854 daigle
		String urlString = null;
1203
		String documentPath = null;
1204 5755 leinfelder
		String errorMsg = null;
1205 4854 daigle
		try {
1206
			// try to open a https stream to test if the request server's public
1207
			// key
1208
			// in the key store, this is security issue
1209
			String server = params.get("server")[0];
1210
			urlString = "https://" + server + "?server="
1211
					+ MetacatUtil.getLocalReplicationServerName() + "&action=test";
1212
			URL u = new URL(urlString);
1213 5014 daigle
			String test = ReplicationService.getURLContent(u);
1214 4854 daigle
			// couldn't pass the test
1215
			if (test.indexOf("successfully") == -1) {
1216
				response.setContentType("text/xml");
1217 5755 leinfelder
				Writer out = response.getWriter();
1218
				out.write("<error>Couldn't pass the trust test " + test + " </error>");
1219 4854 daigle
				out.close();
1220
				return;
1221
			}
1222 2286 tao
1223 4854 daigle
			String docid = params.get("docid")[0];
1224 5014 daigle
			logReplication.debug("ReplicationService.handleGetDocumentRequest - MetacatReplication.handleGetDocumentRequest for docid: "
1225
					+ docid);
1226 4854 daigle
			DocumentImpl di = new DocumentImpl(docid);
1227 2286 tao
1228 5014 daigle
			String documentDir = PropertyService
1229
					.getProperty("application.documentfilepath");
1230 4854 daigle
			documentPath = documentDir + FileUtil.getFS() + docid;
1231 4488 daigle
1232 4854 daigle
			// if the document does not exist on disk, read it from db and write
1233
			// it to disk.
1234
			if (FileUtil.getFileStatus(documentPath) == FileUtil.DOES_NOT_EXIST
1235
					|| FileUtil.getFileSize(documentPath) == 0) {
1236 5752 leinfelder
				FileOutputStream fos = new FileOutputStream(documentPath);
1237
				di.toXml(fos, null, null, true);
1238 4854 daigle
			}
1239 2286 tao
1240 5752 leinfelder
			// read the file from disk and send it to outputstream
1241
			OutputStream outputStream = response.getOutputStream();
1242
			di.readFromFileSystem(outputStream, null, null, documentPath);
1243 2286 tao
1244 5014 daigle
			logReplication.info("ReplicationService.handleGetDocumentRequest - document " + docid + " sent");
1245 4854 daigle
1246 5755 leinfelder
			// return to avoid continuing to the error reporting section at the end
1247
			return;
1248
1249 4854 daigle
		} catch (MalformedURLException mue) {
1250 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1251
			logReplication.error("ReplicationService.handleGetDocumentRequest - Url error when getting document from MetacatReplication."
1252 4854 daigle
					+ "handlGetDocumentRequest for url: " + urlString + " : "
1253
					+ mue.getMessage());
1254
			// e.printStackTrace(System.out);
1255 5755 leinfelder
1256 4854 daigle
		} catch (IOException ioe) {
1257 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1258
			logReplication.error("ReplicationService.handleGetDocumentRequest - I/O error when getting document from MetacatReplication."
1259
					+ "handlGetDocumentRequest for file: " + documentPath + " : "
1260
					+ ioe.getMessage());
1261 5755 leinfelder
			errorMsg = ioe.getMessage();
1262 4854 daigle
		} catch (PropertyNotFoundException pnfe) {
1263 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1264
			logReplication
1265
					.error("ReplicationService.handleGetDocumentRequest - Error getting property when getting document from MetacatReplication."
1266
							+ "handlGetDocumentRequest for file: "
1267
							+ documentPath
1268
							+ " : "
1269
							+ pnfe.getMessage());
1270 4854 daigle
			// e.printStackTrace(System.out);
1271 5755 leinfelder
			errorMsg = pnfe.getMessage();
1272 4854 daigle
		} catch (McdbException me) {
1273 5014 daigle
			logReplication
1274
					.error("ReplicationService.handleGetDocumentRequest - Document implementation error  getting property when getting document from MetacatReplication."
1275
							+ "handlGetDocumentRequest for file: "
1276
							+ documentPath
1277
							+ " : "
1278
							+ me.getMessage());
1279 4854 daigle
			// e.printStackTrace(System.out);
1280 5755 leinfelder
			errorMsg = me.getMessage();
1281 4854 daigle
		}
1282 5755 leinfelder
1283
		// report any errors if we got here
1284
		response.setContentType("text/xml");
1285
		Writer out = null;
1286
		try {
1287
			response.getWriter();
1288
			out = response.getWriter();
1289
			out.write("<error>" + errorMsg + "</error>");
1290
		} catch (Exception e) {
1291
			logMetacat.error(e.getMessage(), e);
1292
		} finally {
1293
			try {
1294
				out.close();
1295
			} catch (IOException e) {
1296
				logMetacat.error(e.getMessage(), e);
1297
			}
1298
		}
1299
1300 4854 daigle
1301
	}
1302
1303 5014 daigle
	/**
1304 4854 daigle
	 * Sends a list of all of the documents on this sever along with their
1305
	 * revision numbers. The format is: <!ELEMENT replication (server, updates)>
1306
	 * <!ELEMENT server (#PCDATA)> <!ELEMENT updates ((updatedDocument |
1307
	 * deleteDocument | revisionDocument)*)> <!ELEMENT updatedDocument (docid,
1308
	 * rev, datafile*)> <!ELEMENT deletedDocument (docid, rev)> <!ELEMENT
1309
	 * revisionDocument (docid, rev, datafile*)> <!ELEMENT docid (#PCDATA)>
1310
	 * <!ELEMENT rev (#PCDATA)> <!ELEMENT datafile (#PCDATA)> note that the rev
1311
	 * in deletedDocument is always empty. I just left it in there to make the
1312
	 * parser implementation easier.
1313
	 */
1314 5755 leinfelder
	protected static void handleUpdateRequest(Hashtable<String, String[]> params,
1315 5014 daigle
			HttpServletResponse response) {
1316
		// Checked out DBConnection
1317
		DBConnection dbConn = null;
1318
		// DBConenction serial number when checked it out
1319
		int serialNumber = -1;
1320
		PreparedStatement pstmt = null;
1321
		// Server list to store server info of xml_replication table
1322
		ReplicationServerList serverList = null;
1323 5755 leinfelder
1324
		// a writer for response
1325
		Writer out = null;
1326 2286 tao
1327 5014 daigle
		try {
1328 5755 leinfelder
			// get writer, TODO: encoding?
1329
			response.setContentType("text/xml");
1330
			out = response.getWriter();
1331
1332 5014 daigle
			// Check out a DBConnection from pool
1333
			dbConn = DBConnectionPool
1334
					.getDBConnection("MetacatReplication.handleUpdateRequest");
1335
			serialNumber = dbConn.getCheckOutSerialNumber();
1336
			// Create a server list from xml_replication table
1337
			serverList = new ReplicationServerList();
1338 2286 tao
1339 5014 daigle
			// Get remote server name from param
1340
			String server = ((String[]) params.get("server"))[0];
1341
			// If no servr name in param, return a error
1342
			if (server == null || server.equals("")) {
1343 5755 leinfelder
				out.write("<error>Request didn't specify server name</error>");
1344 5014 daigle
				out.close();
1345
				return;
1346
			}//if
1347 2286 tao
1348 5014 daigle
			//try to open a https stream to test if the request server's public key
1349
			//in the key store, this is security issue
1350 5440 berkley
			String testUrl = "https://" + server + "?server="
1351 5441 berkley
            + MetacatUtil.getLocalReplicationServerName() + "&action=test";
1352 5440 berkley
			logReplication.info("Running trust test: " + testUrl);
1353
			URL u = new URL(testUrl);
1354 5014 daigle
			String test = ReplicationService.getURLContent(u);
1355 5441 berkley
			logReplication.info("Ouput from test is '" + test + "'");
1356 5014 daigle
			//couldn't pass the test
1357
			if (test.indexOf("successfully") == -1) {
1358 5441 berkley
			    logReplication.error("Trust test failed.");
1359 5755 leinfelder
				out.write("<error>Couldn't pass the trust test</error>");
1360 5014 daigle
				out.close();
1361
				return;
1362
			}
1363 5441 berkley
			logReplication.info("Trust test succeeded.");
1364 2286 tao
1365 5014 daigle
			// Check if local host configure to replicate xml documents to remote
1366
			// server. If not send back a error message
1367
			if (!serverList.getReplicationValue(server)) {
1368 5755 leinfelder
				out.write("<error>Configuration not allow to replicate document to you</error>");
1369 5014 daigle
				out.close();
1370
				return;
1371
			}//if
1372 2286 tao
1373 5014 daigle
			// Store the sql command
1374
			StringBuffer docsql = new StringBuffer();
1375
			StringBuffer revisionSql = new StringBuffer();
1376
			// Stroe the docid list
1377
			StringBuffer doclist = new StringBuffer();
1378
			// Store the deleted docid list
1379
			StringBuffer delsql = new StringBuffer();
1380
			// Store the data set file
1381
			Vector<Vector<String>> packageFiles = new Vector<Vector<String>>();
1382 2286 tao
1383 5014 daigle
			// Append local server's name and replication servlet to doclist
1384
			doclist.append("<?xml version=\"1.0\"?><replication>");
1385
			doclist.append("<server>")
1386
					.append(MetacatUtil.getLocalReplicationServerName());
1387
			//doclist.append(util.getProperty("replicationpath"));
1388
			doclist.append("</server><updates>");
1389 2286 tao
1390 5014 daigle
			// Get correct docid that reside on this server according the requesting
1391
			// server's replicate and data replicate value in xml_replication table
1392 5319 jones
			docsql.append(DatabaseService.getInstance().getDBAdapter().getReplicationDocumentListSQL());
1393 5014 daigle
			//docsql.append("select docid, rev, doctype from xml_documents where (docid not in (select a.docid from xml_documents a, xml_revisions b where a.docid=b.docid and a.rev<=b.rev)) ");
1394
			revisionSql.append("select docid, rev, doctype from xml_revisions ");
1395
			// If the localhost is not a hub to the remote server, only replicate
1396
			// the docid' which home server is local host (server_location =1)
1397
			if (!serverList.getHubValue(server)) {
1398
				String serverLocationDoc = " and a.server_location = 1";
1399
				String serverLocationRev = "where server_location = 1";
1400
				docsql.append(serverLocationDoc);
1401
				revisionSql.append(serverLocationRev);
1402
			}
1403
			logReplication.info("ReplicationService.handleUpdateRequest - Doc sql: " + docsql.toString());
1404 2286 tao
1405 5014 daigle
			// Get any deleted documents
1406
			delsql.append("select distinct docid from ");
1407
			delsql.append("xml_revisions where docid not in (select docid from ");
1408
			delsql.append("xml_documents) ");
1409
			// If the localhost is not a hub to the remote server, only replicate
1410
			// the docid' which home server is local host (server_location =1)
1411
			if (!serverList.getHubValue(server)) {
1412
				delsql.append("and server_location = 1");
1413
			}
1414
			logReplication.info("ReplicationService.handleUpdateRequest - Deleted sql: " + delsql.toString());
1415 2286 tao
1416 5014 daigle
			// Get docid list of local host
1417
			pstmt = dbConn.prepareStatement(docsql.toString());
1418
			pstmt.execute();
1419
			ResultSet rs = pstmt.getResultSet();
1420
			boolean tablehasrows = rs.next();
1421
			//If metacat configed to replicate data file
1422
			//if ((util.getProperty("replicationsenddata")).equals("on"))
1423
			boolean replicateData = serverList.getDataReplicationValue(server);
1424
			if (replicateData) {
1425
				while (tablehasrows) {
1426
					String recordDoctype = rs.getString(3);
1427
					Vector<String> packagedoctypes = MetacatUtil
1428
							.getOptionList(PropertyService
1429
									.getProperty("xml.packagedoctype"));
1430
					//if this is a package file, put it at the end
1431
					//because if a package file is read before all of the files it
1432
					//refers to are loaded then there is an error
1433
					if (recordDoctype != null && !packagedoctypes.contains(recordDoctype)) {
1434
						//If this is not data file
1435
						if (!recordDoctype.equals("BIN")) {
1436
							//for non-data file document
1437
							doclist.append("<updatedDocument>");
1438
							doclist.append("<docid>").append(rs.getString(1));
1439
							doclist.append("</docid><rev>").append(rs.getInt(2));
1440
							doclist.append("</rev>");
1441
							doclist.append("</updatedDocument>");
1442
						}//if
1443
						else {
1444
							//for data file document, in datafile attributes
1445
							//we put "datafile" value there
1446
							doclist.append("<updatedDocument>");
1447
							doclist.append("<docid>").append(rs.getString(1));
1448
							doclist.append("</docid><rev>").append(rs.getInt(2));
1449
							doclist.append("</rev>");
1450
							doclist.append("<datafile>");
1451
							doclist.append(PropertyService
1452
									.getProperty("replication.datafileflag"));
1453
							doclist.append("</datafile>");
1454
							doclist.append("</updatedDocument>");
1455
						}//else
1456
					}//if packagedoctpes
1457
					else { //the package files are saved to be put into the xml later.
1458
						Vector<String> v = new Vector<String>();
1459
						v.add(rs.getString(1));
1460
						v.add(String.valueOf(rs.getInt(2)));
1461
						packageFiles.add(v);
1462
					}//esle
1463
					tablehasrows = rs.next();
1464
				}//while
1465
			}//if
1466
			else //metacat was configured not to send data file
1467
			{
1468
				while (tablehasrows) {
1469
					String recordDoctype = rs.getString(3);
1470
					if (!recordDoctype.equals("BIN")) { //don't replicate data files
1471
						Vector<String> packagedoctypes = MetacatUtil
1472
								.getOptionList(PropertyService
1473
										.getProperty("xml.packagedoctype"));
1474
						if (recordDoctype != null
1475
								&& !packagedoctypes.contains(recordDoctype)) { //if this is a package file, put it at the end
1476
							//because if a package file is read before all of the files it
1477
							//refers to are loaded then there is an error
1478
							doclist.append("<updatedDocument>");
1479
							doclist.append("<docid>").append(rs.getString(1));
1480
							doclist.append("</docid><rev>").append(rs.getInt(2));
1481
							doclist.append("</rev>");
1482
							doclist.append("</updatedDocument>");
1483
						} else { //the package files are saved to be put into the xml later.
1484
							Vector<String> v = new Vector<String>();
1485
							v.add(rs.getString(1));
1486
							v.add(String.valueOf(rs.getInt(2)));
1487
							packageFiles.add(v);
1488
						}
1489
					}//if
1490
					tablehasrows = rs.next();
1491
				}//while
1492
			}//else
1493 2286 tao
1494 5014 daigle
			pstmt = dbConn.prepareStatement(delsql.toString());
1495
			//usage count should increas 1
1496
			dbConn.increaseUsageCount(1);
1497 2286 tao
1498 5014 daigle
			pstmt.execute();
1499
			rs = pstmt.getResultSet();
1500
			tablehasrows = rs.next();
1501
			while (tablehasrows) { //handle the deleted documents
1502
				doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1503
				doclist.append("</docid><rev></rev></deletedDocument>");
1504
				//note that rev is always empty for deleted docs
1505
				tablehasrows = rs.next();
1506
			}
1507 2286 tao
1508 5014 daigle
			//now we can put the package files into the xml results
1509
			for (int i = 0; i < packageFiles.size(); i++) {
1510
				Vector<String> v = packageFiles.elementAt(i);
1511
				doclist.append("<updatedDocument>");
1512
				doclist.append("<docid>").append(v.elementAt(0));
1513
				doclist.append("</docid><rev>");
1514
				doclist.append(v.elementAt(1));
1515
				doclist.append("</rev>");
1516
				doclist.append("</updatedDocument>");
1517
			}
1518
			// add revision doc list
1519
			doclist.append(prepareRevisionDoc(dbConn, revisionSql.toString(),
1520
					replicateData));
1521 6118 leinfelder
1522 6135 leinfelder
			// add the system metadata entries if configured to replicate them
1523
			boolean replicateSystemMetadata = serverList.getSystemMetadataReplicationValue(server);
1524
			if (replicateSystemMetadata) {
1525
				Date since = new Date(System.currentTimeMillis());
1526
				since = serverList.getLastCheckedDate(server);
1527
				List<String> systemMetadataEntries =
1528
					IdentifierManager.getInstance().getUpdatedSystemMetadataIds(since);
1529
				for (int i = 0; i < systemMetadataEntries.size(); i++) {
1530
					String guid = systemMetadataEntries.get(i);
1531
					doclist.append("<updatedSystemMetadata>");
1532
					doclist.append("<guid>");
1533
					doclist.append(guid);
1534
					doclist.append("</guid>");
1535
					doclist.append("</updatedSystemMetadata>");
1536
				}
1537 6118 leinfelder
			}
1538 2286 tao
1539 5014 daigle
			doclist.append("</updates></replication>");
1540
			logReplication.info("ReplicationService.handleUpdateRequest - doclist: " + doclist.toString());
1541
			pstmt.close();
1542
			//conn.close();
1543 5755 leinfelder
			out.write(doclist.toString());
1544 2286 tao
1545 5014 daigle
		} catch (Exception e) {
1546
			logMetacat.error("ReplicationService.handleUpdateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1547
			logReplication.error("ReplicationService.handleUpdateRequest - error in MetacatReplication." + "handleupdaterequest: "
1548
					+ e.getMessage());
1549
			//e.printStackTrace(System.out);
1550 5755 leinfelder
			try {
1551
				out.write("<error>" + e.getMessage() + "</error>");
1552
			} catch (IOException e1) {
1553
				logMetacat.error(e1.getMessage(), e1);
1554
			}
1555 5014 daigle
		} finally {
1556
			try {
1557
				pstmt.close();
1558
			}//try
1559
			catch (SQLException ee) {
1560
				logMetacat.error("ReplicationService.handleUpdateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1561
				logReplication.error("ReplicationService.handleUpdateRequest - Error in MetacatReplication."
1562
						+ "handleUpdaterequest to close pstmt: " + ee.getMessage());
1563
			}//catch
1564
			finally {
1565
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1566
			}//finally
1567 5755 leinfelder
			try {
1568
				out.close();
1569
			} catch (IOException e) {
1570
				logMetacat.error(e.getMessage(), e);
1571
			}
1572 5014 daigle
		}//finally
1573 2286 tao
1574 5014 daigle
	}//handlUpdateRequest
1575 2286 tao
1576 6015 leinfelder
	/**
1577
	 *
1578
	 * @param dbConn connection for doing the update
1579
	 * @param docid the document id to update
1580
	 * @param owner the user_owner
1581
	 * @param updater the user_updated
1582
	 * @throws SQLException
1583
	 */
1584
	public static void updateUserOwner(DBConnection dbConn, String docid, String owner, String updater) throws SQLException {
1585
1586
		String sql =
1587
			"UPDATE xml_documents " +
1588
			"SET user_owner = ?, " +
1589
			"user_updated = ? " +
1590
			"WHERE docid = ?;";
1591
		PreparedStatement pstmt = dbConn.prepareStatement(sql);
1592
		//usage count should increas 1
1593
		dbConn.increaseUsageCount(1);
1594
1595
		docid = DocumentUtil.getSmartDocId(docid);
1596
		pstmt.setString(1, owner);
1597
		pstmt.setString(2, updater);
1598
		pstmt.setString(3, docid);
1599
		pstmt.execute();
1600
		pstmt.close();
1601
1602
		dbConn.commit();
1603
	}
1604
1605 5014 daigle
	/*
1606
	 * This method will get the xml string for document in xml_revision
1607
	 * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1608
	 */
1609
	private static String prepareRevisionDoc(DBConnection dbConn, String revSql,
1610
			boolean replicateData) throws Exception {
1611
		logReplication.warn("ReplicationService.prepareRevisionDoc - The revision document sql is " + revSql);
1612
		StringBuffer revDocList = new StringBuffer();
1613
		PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1614
		//usage count should increas 1
1615
		dbConn.increaseUsageCount(1);
1616 2286 tao
1617 5014 daigle
		pstmt.execute();
1618
		ResultSet rs = pstmt.getResultSet();
1619
		boolean tablehasrows = rs.next();
1620
		while (tablehasrows) {
1621
			String recordDoctype = rs.getString(3);
1622 2286 tao
1623 5014 daigle
			//If this is data file and it isn't configured to replicate data
1624
			if (recordDoctype.equals("BIN") && !replicateData) {
1625
				// do nothing
1626
				continue;
1627
			} else {
1628 2597 tao
1629 5014 daigle
				revDocList.append("<revisionDocument>");
1630
				revDocList.append("<docid>").append(rs.getString(1));
1631
				revDocList.append("</docid><rev>").append(rs.getInt(2));
1632
				revDocList.append("</rev>");
1633
				// data file
1634
				if (recordDoctype.equals("BIN")) {
1635
					revDocList.append("<datafile>");
1636
					revDocList.append(PropertyService
1637
							.getProperty("replication.datafileflag"));
1638
					revDocList.append("</datafile>");
1639
				}
1640
				revDocList.append("</revisionDocument>");
1641 2286 tao
1642 5014 daigle
			}//else
1643
			tablehasrows = rs.next();
1644
		}
1645
		//System.out.println("The revision list is"+ revDocList.toString());
1646
		return revDocList.toString();
1647
	}
1648 2286 tao
1649 5014 daigle
	/**
1650
	 * Returns the xml_catalog table encoded in xml
1651
	 */
1652
	public static String getCatalogXML() {
1653 5755 leinfelder
		return handleGetCatalogRequest(null, null, false);
1654 5014 daigle
	}
1655 2286 tao
1656 5014 daigle
	/**
1657
	 * Sends the contents of the xml_catalog table encoded in xml
1658
	 * The xml format is:
1659
	 * <!ELEMENT xml_catalog (row*)>
1660
	 * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1661
	 *                system_id)>
1662
	 * All of the sub elements of row are #PCDATA
1663 2286 tao
1664 5014 daigle
	 * If printFlag == false then do not print to out.
1665
	 */
1666 5755 leinfelder
	protected static String handleGetCatalogRequest(
1667 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
1668
			boolean printFlag) {
1669
		DBConnection dbConn = null;
1670
		int serialNumber = -1;
1671
		PreparedStatement pstmt = null;
1672 5755 leinfelder
		Writer out = null;
1673 5014 daigle
		try {
1674 5755 leinfelder
			// get writer, TODO: encoding?
1675 5944 berkley
		    if(printFlag)
1676
		    {
1677
		        response.setContentType("text/xml");
1678
		        out = response.getWriter();
1679
		    }
1680 5014 daigle
			/*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1681
			                                          "handleGetCatalogRequest");*/
1682
			dbConn = DBConnectionPool
1683
					.getDBConnection("MetacatReplication.handleGetCatalogRequest");
1684
			serialNumber = dbConn.getCheckOutSerialNumber();
1685
			pstmt = dbConn.prepareStatement("select entry_type, "
1686
					+ "source_doctype, target_doctype, public_id, "
1687
					+ "system_id from xml_catalog");
1688
			pstmt.execute();
1689
			ResultSet rs = pstmt.getResultSet();
1690
			boolean tablehasrows = rs.next();
1691
			StringBuffer sb = new StringBuffer();
1692
			sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1693
			while (tablehasrows) {
1694
				sb.append("<row><entry_type>").append(rs.getString(1));
1695
				sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1696
				sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1697
				sb.append("</target_doctype><public_id>").append(rs.getString(4));
1698
				// system id may not have server url on front.  Add it if not.
1699
				String systemID = rs.getString(5);
1700
				if (!systemID.startsWith("http://")) {
1701
					systemID = SystemUtil.getContextURL() + systemID;
1702
				}
1703
				sb.append("</public_id><system_id>").append(systemID);
1704
				sb.append("</system_id></row>");
1705 2286 tao
1706 5014 daigle
				tablehasrows = rs.next();
1707
			}
1708
			sb.append("</xml_catalog>");
1709
			//conn.close();
1710
			if (printFlag) {
1711
				response.setContentType("text/xml");
1712 5755 leinfelder
				out.write(sb.toString());
1713 5014 daigle
			}
1714
			pstmt.close();
1715
			return sb.toString();
1716
		} catch (Exception e) {
1717
			logMetacat.error("ReplicationService.handleGetCatalogRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1718
			logReplication.error("ReplicationService.handleGetCatalogRequest - error in MetacatReplication.handleGetCatalogRequest:"
1719
					+ e.getMessage());
1720
			e.printStackTrace(System.out);
1721
			if (printFlag) {
1722 5755 leinfelder
				try {
1723
					out.write("<error>" + e.getMessage() + "</error>");
1724
				} catch (IOException e1) {
1725
					logMetacat.error(e1.getMessage(), e1);
1726
				}
1727 5014 daigle
			}
1728
		} finally {
1729
			try {
1730
				pstmt.close();
1731
			}//try
1732
			catch (SQLException ee) {
1733
				logMetacat.error("ReplicationService.handleGetCatalogRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1734
				logReplication.error("ReplicationService.handleGetCatalogRequest - Error in MetacatReplication.handleGetCatalogRequest: "
1735
						+ ee.getMessage());
1736
			}//catch
1737
			finally {
1738
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1739
			}//finally
1740 5755 leinfelder
			if (out != null) {
1741
				try {
1742
					out.close();
1743
				} catch (IOException e1) {
1744
					logMetacat.error(e1.getMessage(), e1);
1745
				}
1746
			}
1747 5014 daigle
		}//finally
1748 2286 tao
1749 5014 daigle
		return null;
1750
	}
1751 2286 tao
1752 5014 daigle
	/**
1753
	 * Sends the current system date to the remote server.  Using this action
1754
	 * for replication gets rid of any problems with syncronizing clocks
1755
	 * because a time specific to a document is always kept on its home server.
1756
	 */
1757 5755 leinfelder
	protected static void handleGetTimeRequest(
1758 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1759
		SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
1760
		java.util.Date localtime = new java.util.Date();
1761
		String dateString = formatter.format(localtime);
1762 5755 leinfelder
1763
		// get a writer for sending back to response
1764 5014 daigle
		response.setContentType("text/xml");
1765 5755 leinfelder
		Writer out = null;
1766
		try {
1767
			out = response.getWriter();
1768
			out.write("<timestamp>" + dateString + "</timestamp>");
1769
			out.close();
1770
		} catch (IOException e) {
1771
			logMetacat.error(e.getMessage(), e);
1772
		}
1773
1774 5014 daigle
	}
1775 2286 tao
1776 5014 daigle
	/**
1777
	 * this method handles the timeout for a file lock.  when a lock is
1778
	 * granted it is granted for 30 seconds.  When this thread runs out
1779
	 * it deletes the docid from the queue, thus eliminating the lock.
1780
	 */
1781
	public void run() {
1782
		try {
1783
			logReplication.info("ReplicationService.run - thread started for docid: "
1784
					+ (String) fileLocks.elementAt(0));
1785 2286 tao
1786 5014 daigle
			Thread.sleep(30000); //the lock will expire in 30 seconds
1787
			logReplication.info("thread for docid: "
1788
					+ (String) fileLocks.elementAt(fileLocks.size() - 1) + " exiting.");
1789 2286 tao
1790 5014 daigle
			fileLocks.remove(fileLocks.size() - 1);
1791
			//fileLocks is treated as a FIFO queue.  If there are more than one lock
1792
			//in the vector, the first one inserted will be removed.
1793
		} catch (Exception e) {
1794
			logMetacat.error("ReplicationService.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1795
			logReplication.error("ReplicationService.run - error in file lock thread from "
1796
					+ "MetacatReplication.run: " + e.getMessage());
1797
		}
1798
	}
1799 2286 tao
1800 5014 daigle
	/**
1801
	 * Returns the name of a server given a serverCode
1802
	 * @param serverCode the serverid of the server
1803
	 * @return the servername or null if the specified serverCode does not
1804
	 *         exist.
1805
	 */
1806
	public static String getServerNameForServerCode(int serverCode) {
1807
		//System.out.println("serverid: " + serverCode);
1808
		DBConnection dbConn = null;
1809
		int serialNumber = -1;
1810
		PreparedStatement pstmt = null;
1811
		try {
1812
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.getServer");
1813
			serialNumber = dbConn.getCheckOutSerialNumber();
1814
			String sql = new String("select server from "
1815
					+ "xml_replication where serverid = " + serverCode);
1816
			pstmt = dbConn.prepareStatement(sql);
1817
			//System.out.println("getserver sql: " + sql);
1818
			pstmt.execute();
1819
			ResultSet rs = pstmt.getResultSet();
1820
			boolean tablehasrows = rs.next();
1821
			if (tablehasrows) {
1822
				//System.out.println("server: " + rs.getString(1));
1823
				return rs.getString(1);
1824
			}
1825 2286 tao
1826 5014 daigle
			//conn.close();
1827
		} catch (Exception e) {
1828
			logMetacat.error("ReplicationService.getServerNameForServerCode - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1829
			logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacatReplication.getServer: " + e.getMessage());
1830
		} finally {
1831
			try {
1832
				pstmt.close();
1833
			}//try
1834
			catch (SQLException ee) {
1835
				logMetacat.error("ReplicationService.getServerNameForServerCode - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1836
				logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacactReplication.getserver: "
1837
						+ ee.getMessage());
1838
			}//catch
1839
			finally {
1840
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1841
			}//fianlly
1842
		}//finally
1843 2286 tao
1844 5014 daigle
		return null;
1845
		//return null if the server does not exist
1846
	}
1847 2286 tao
1848 5014 daigle
	/**
1849
	 * Returns a server code given a server name
1850
	 * @param server the name of the server
1851
	 * @return integer > 0 representing the code of the server, 0 if the server
1852
	 *  does not exist.
1853
	 */
1854
	public static int getServerCodeForServerName(String server) throws ServiceException {
1855
		DBConnection dbConn = null;
1856
		int serialNumber = -1;
1857
		PreparedStatement pstmt = null;
1858
		int serverCode = 0;
1859 2286 tao
1860 5014 daigle
		try {
1861 837 bojilova
1862 5014 daigle
			//conn = util.openDBConnection();
1863
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.getServerCode");
1864
			serialNumber = dbConn.getCheckOutSerialNumber();
1865
			pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication "
1866
					+ "WHERE server LIKE '" + server + "'");
1867
			pstmt.execute();
1868
			ResultSet rs = pstmt.getResultSet();
1869
			boolean tablehasrows = rs.next();
1870
			if (tablehasrows) {
1871
				serverCode = rs.getInt(1);
1872
				pstmt.close();
1873
				//conn.close();
1874
				return serverCode;
1875
			}
1876 837 bojilova
1877 5014 daigle
		} catch (SQLException sqle) {
1878
			throw new ServiceException("ReplicationService.getServerCodeForServerName - "
1879
					+ "SQL error when getting server code: " + sqle.getMessage());
1880 2286 tao
1881 5014 daigle
		} finally {
1882
			try {
1883
				pstmt.close();
1884
				//conn.close();
1885
			}//try
1886
			catch (Exception ee) {
1887
				logMetacat.error("ReplicationService.getServerCodeForServerName - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1888
				logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacatReplicatio.getServerCode: "
1889
						+ ee.getMessage());
1890 837 bojilova
1891 5014 daigle
			}//catch
1892
			finally {
1893
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1894
			}//finally
1895
		}//finally
1896 2286 tao
1897 5014 daigle
		return serverCode;
1898
	}
1899 2286 tao
1900 5014 daigle
	/**
1901
	 * Method to get a host server information for given docid
1902
	 * @param conn a connection to the database
1903
	 */
1904
	public static Hashtable<String, String> getHomeServerInfoForDocId(String docId) {
1905
		Hashtable<String, String> sl = new Hashtable<String, String>();
1906
		DBConnection dbConn = null;
1907
		int serialNumber = -1;
1908 5027 daigle
		docId = DocumentUtil.getDocIdFromString(docId);
1909 5014 daigle
		PreparedStatement pstmt = null;
1910
		int serverLocation;
1911
		try {
1912
			//get conection
1913
			dbConn = DBConnectionPool.getDBConnection("ReplicationHandler.getHomeServer");
1914
			serialNumber = dbConn.getCheckOutSerialNumber();
1915
			//get a server location from xml_document table
1916
			pstmt = dbConn.prepareStatement("select server_location from xml_documents "
1917
					+ "where docid = ?");
1918
			pstmt.setString(1, docId);
1919
			pstmt.execute();
1920
			ResultSet serverName = pstmt.getResultSet();
1921
			//get a server location
1922
			if (serverName.next()) {
1923
				serverLocation = serverName.getInt(1);
1924
				pstmt.close();
1925
			} else {
1926
				pstmt.close();
1927
				//ut.returnConnection(conn);
1928
				return null;
1929
			}
1930
			pstmt = dbConn.prepareStatement("select server, last_checked, replicate "
1931
					+ "from xml_replication where serverid = ?");
1932
			//increase usage count
1933
			dbConn.increaseUsageCount(1);
1934
			pstmt.setInt(1, serverLocation);
1935
			pstmt.execute();
1936
			ResultSet rs = pstmt.getResultSet();
1937
			boolean tableHasRows = rs.next();
1938
			if (tableHasRows) {
1939 2286 tao
1940 5014 daigle
				String server = rs.getString(1);
1941
				String last_checked = rs.getString(2);
1942
				if (!server.equals("localhost")) {
1943
					sl.put(server, last_checked);
1944
				}
1945 2286 tao
1946 5014 daigle
			} else {
1947
				pstmt.close();
1948
				//ut.returnConnection(conn);
1949
				return null;
1950
			}
1951
			pstmt.close();
1952
		} catch (Exception e) {
1953
			logMetacat.error("ReplicationService.getHomeServerInfoForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1954
			logReplication.error("ReplicationService.getHomeServerInfoForDocId - error in replicationHandler.getHomeServer(): "
1955
					+ e.getMessage());
1956
		} finally {
1957
			try {
1958
				pstmt.close();
1959
				//ut.returnConnection(conn);
1960
			} catch (Exception ee) {
1961
				logMetacat.error("ReplicationService.getHomeServerInfoForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1962
				logReplication.error("ReplicationService.getHomeServerInfoForDocId - Eror irn rplicationHandler.getHomeServer() "
1963
						+ "to close pstmt: " + ee.getMessage());
1964
			} finally {
1965
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1966
			}
1967 2286 tao
1968 5014 daigle
		}//finally
1969
		return sl;
1970
	}
1971 2286 tao
1972 5014 daigle
	/**
1973
	 * Returns a home server location  given a accnum
1974
	 * @param accNum , given accNum for a document
1975
	 *
1976
	 */
1977
	public static int getHomeServerCodeForDocId(String accNum) throws ServiceException {
1978
		DBConnection dbConn = null;
1979
		int serialNumber = -1;
1980
		PreparedStatement pstmt = null;
1981
		int serverCode = 1;
1982 5027 daigle
		String docId = DocumentUtil.getDocIdFromString(accNum);
1983 2286 tao
1984 5014 daigle
		try {
1985 1292 tao
1986 5014 daigle
			// Get DBConnection
1987
			dbConn = DBConnectionPool
1988
					.getDBConnection("ReplicationHandler.getServerLocation");
1989
			serialNumber = dbConn.getCheckOutSerialNumber();
1990
			pstmt = dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1991
					+ "WHERE docid LIKE '" + docId + "'");
1992
			pstmt.execute();
1993
			ResultSet rs = pstmt.getResultSet();
1994
			boolean tablehasrows = rs.next();
1995
			//If a document is find, return the server location for it
1996
			if (tablehasrows) {
1997
				serverCode = rs.getInt(1);
1998
				pstmt.close();
1999
				//conn.close();
2000
				return serverCode;
2001
			}
2002
			//if couldn't find in xml_documents table, we think server code is 1
2003
			//(this is new document)
2004
			else {
2005
				pstmt.close();
2006
				//conn.close();
2007
				return serverCode;
2008
			}
2009 1292 tao
2010 5014 daigle
		} catch (SQLException sqle) {
2011
			throw new ServiceException("ReplicationService.getHomeServerCodeForDocId - "
2012
					+ "SQL error when getting home server code for docid: " + docId + " : "
2013
					+ sqle.getMessage());
2014 2286 tao
2015 5014 daigle
		} finally {
2016
			try {
2017
				pstmt.close();
2018
				//conn.close();
2019 2286 tao
2020 5014 daigle
			} catch (SQLException sqle) {
2021
				logMetacat.error("ReplicationService.getHomeServerCodeForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2022
				logReplication.error("ReplicationService.getHomeServerCodeForDocId - ReplicationService.getHomeServerCodeForDocId - "
2023
						+ "SQL error when getting home server code for docid: " + docId + " : "
2024
						+ sqle.getMessage());
2025
			} finally {
2026
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2027
			}//finally
2028
		}//finally
2029
		//return serverCode;
2030
	}
2031 1292 tao
2032 5014 daigle
	/**
2033
	 * This method returns the content of a url
2034
	 * @param u the url to return the content from
2035
	 * @return a string representing the content of the url
2036
	 * @throws java.io.IOException
2037
	 */
2038
	public static String getURLContent(URL u) throws java.io.IOException {
2039 5441 berkley
	    logReplication.info("Getting url content from " + u.toString());
2040 5014 daigle
		char istreamChar;
2041
		int istreamInt;
2042 5440 berkley
		logReplication.info("ReplicationService.getURLContent - Before open the stream" + u.toString());
2043 5014 daigle
		InputStream input = u.openStream();
2044 5440 berkley
		logReplication.info("ReplicationService.getURLContent - After open the stream" + u.toString());
2045 5014 daigle
		InputStreamReader istream = new InputStreamReader(input);
2046
		StringBuffer serverResponse = new StringBuffer();
2047
		while ((istreamInt = istream.read()) != -1) {
2048
			istreamChar = (char) istreamInt;
2049
			serverResponse.append(istreamChar);
2050
		}
2051
		istream.close();
2052
		input.close();
2053 2286 tao
2054 5014 daigle
		return serverResponse.toString();
2055
	}
2056 2286 tao
2057 5014 daigle
//	/**
2058
//	 * Method for writing replication messages to a log file specified in
2059
//	 * metacat.properties
2060
//	 */
2061
//	public static void replLog(String message) {
2062
//		try {
2063
//			FileOutputStream fos = new FileOutputStream(PropertyService
2064
//					.getProperty("replication.logdir")
2065
//					+ "/metacatreplication.log", true);
2066
//			PrintWriter pw = new PrintWriter(fos);
2067
//			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
2068
//			java.util.Date localtime = new java.util.Date();
2069
//			String dateString = formatter.format(localtime);
2070
//			dateString += " :: " + message;
2071
//			// time stamp each entry
2072
//			pw.println(dateString);
2073
//			pw.flush();
2074
//		} catch (Exception e) {
2075
//			logReplication.error("error writing to replication log from "
2076
//					+ "MetacatReplication.replLog: " + e.getMessage());
2077
//			// e.printStackTrace(System.out);
2078
//		}
2079
//	}
2080 2286 tao
2081 5014 daigle
//	/**
2082
//	 * Method for writing replication messages to a log file specified in
2083
//	 * metacat.properties
2084
//	 */
2085
//	public static void replErrorLog(String message) {
2086
//		try {
2087
//			FileOutputStream fos = new FileOutputStream(PropertyService
2088
//					.getProperty("replication.logdir")
2089
//					+ "/metacatreplicationerror.log", true);
2090
//			PrintWriter pw = new PrintWriter(fos);
2091
//			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
2092
//			java.util.Date localtime = new java.util.Date();
2093
//			String dateString = formatter.format(localtime);
2094
//			dateString += " :: " + message;
2095
//			//time stamp each entry
2096
//			pw.println(dateString);
2097
//			pw.flush();
2098
//		} catch (Exception e) {
2099
//			logReplication.error("error writing to replication error log from "
2100
//					+ "MetacatReplication.replErrorLog: " + e.getMessage());
2101
//			//e.printStackTrace(System.out);
2102
//		}
2103
//	}
2104 2286 tao
2105 5014 daigle
	/**
2106
	 * Returns true if the replicate field for server in xml_replication is 1.
2107
	 * Returns false otherwise
2108 4080 daigle
	 */
2109 5014 daigle
	public static boolean replToServer(String server) {
2110
		DBConnection dbConn = null;
2111
		int serialNumber = -1;
2112
		PreparedStatement pstmt = null;
2113 4080 daigle
		try {
2114 5014 daigle
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.repltoServer");
2115
			serialNumber = dbConn.getCheckOutSerialNumber();
2116
			pstmt = dbConn.prepareStatement("select replicate from "
2117
					+ "xml_replication where server like '" + server + "'");
2118
			pstmt.execute();
2119
			ResultSet rs = pstmt.getResultSet();
2120
			boolean tablehasrows = rs.next();
2121
			if (tablehasrows) {
2122
				int i = rs.getInt(1);
2123
				if (i == 1) {
2124
					pstmt.close();
2125
					//conn.close();
2126
					return true;
2127
				} else {
2128
					pstmt.close();
2129
					//conn.close();
2130
					return false;
2131
				}
2132
			}
2133
		} catch (SQLException sqle) {
2134
			logMetacat.error("ReplicationService.replToServer - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2135
			logReplication.error("ReplicationService.replToServer - SQL error in MetacatReplication.replToServer: "
2136
					+ sqle.getMessage());
2137
		} finally {
2138
			try {
2139
				pstmt.close();
2140
				//conn.close();
2141
			}//try
2142
			catch (Exception ee) {
2143
				logMetacat.error("ReplicationService.replToServer - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2144
				logReplication.error("ReplicationService.replToServer - Error in MetacatReplication.replToServer: "
2145
						+ ee.getMessage());
2146
			}//catch
2147
			finally {
2148
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2149
			}//finally
2150
		}//finally
2151
		return false;
2152
		//the default if this server does not exist is to not replicate to it.
2153 4080 daigle
	}
2154 2286 tao
2155 522 berkley
}