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 6102 leinfelder
import java.io.ByteArrayInputStream;
30
import java.io.ByteArrayOutputStream;
31 5755 leinfelder
import java.io.File;
32
import java.io.FileInputStream;
33
import java.io.FileNotFoundException;
34
import java.io.FileOutputStream;
35
import java.io.IOException;
36
import java.io.InputStream;
37
import java.io.OutputStream;
38
import java.io.StringReader;
39
import java.io.Writer;
40
import java.net.MalformedURLException;
41
import java.net.URL;
42 6582 leinfelder
import java.security.PrivateKey;
43
import java.security.cert.X509Certificate;
44 5755 leinfelder
import java.sql.PreparedStatement;
45
import java.sql.ResultSet;
46
import java.sql.SQLException;
47 6595 leinfelder
import java.sql.Timestamp;
48 8491 slaughter
import java.util.ArrayList;
49
import java.util.Arrays;
50 6595 leinfelder
import java.util.Calendar;
51 2572 tao
import java.util.Date;
52 8689 leinfelder
import java.util.HashMap;
53 5755 leinfelder
import java.util.Hashtable;
54 8491 slaughter
import java.util.List;
55 8689 leinfelder
import java.util.Map;
56 5755 leinfelder
import java.util.Timer;
57
import java.util.Vector;
58 4080 daigle
59 5755 leinfelder
import javax.servlet.http.HttpServletRequest;
60
import javax.servlet.http.HttpServletResponse;
61 574 berkley
62 8299 jones
import org.apache.commons.io.IOUtils;
63 9152 rnahf
import org.apache.commons.lang.exception.ExceptionUtils;
64
import org.apache.http.HttpEntity;
65 9151 rnahf
import org.apache.http.HttpResponse;
66 9152 rnahf
import org.apache.http.StatusLine;
67
import org.apache.http.client.ClientProtocolException;
68 9149 rnahf
import org.apache.http.client.HttpClient;
69 9152 rnahf
import org.apache.http.client.HttpResponseException;
70 9149 rnahf
import org.apache.http.impl.client.HttpClientBuilder;
71
import org.apache.http.impl.client.HttpClients;
72
import org.apache.http.client.config.RequestConfig;
73 5755 leinfelder
import org.apache.log4j.Logger;
74 9096 leinfelder
import org.dataone.client.auth.CertificateManager;
75 9149 rnahf
import org.dataone.client.rest.RestClient;
76 9594 tao
import org.dataone.client.types.AutoCloseHttpClientInputStream;
77 9149 rnahf
import org.dataone.client.utils.HttpUtils;
78 9833 tao
import org.dataone.exceptions.MarshallingException;
79 8491 slaughter
import org.dataone.service.types.v1.Identifier;
80 8810 leinfelder
import org.dataone.service.types.v2.SystemMetadata;
81 6614 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
82 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
83 5755 leinfelder
import org.xml.sax.InputSource;
84
import org.xml.sax.SAXException;
85
import org.xml.sax.XMLReader;
86
87 5014 daigle
import edu.ucsb.nceas.metacat.DocumentImpl;
88
import edu.ucsb.nceas.metacat.DocumentImplWrapper;
89
import edu.ucsb.nceas.metacat.EventLog;
90 5755 leinfelder
import edu.ucsb.nceas.metacat.IdentifierManager;
91
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
92 5014 daigle
import edu.ucsb.nceas.metacat.McdbException;
93 5195 daigle
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlException;
94 5089 daigle
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile;
95 5195 daigle
import edu.ucsb.nceas.metacat.accesscontrol.PermOrderException;
96 7519 leinfelder
import edu.ucsb.nceas.metacat.admin.upgrade.RemoveInvalidReplicas;
97 8746 leinfelder
import edu.ucsb.nceas.metacat.admin.upgrade.UpdateDOI;
98 7175 leinfelder
import edu.ucsb.nceas.metacat.admin.upgrade.dataone.GenerateORE;
99 7170 leinfelder
import edu.ucsb.nceas.metacat.admin.upgrade.dataone.GenerateSystemMetadata;
100 6001 cjones
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException;
101 5014 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
102
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
103
import edu.ucsb.nceas.metacat.database.DatabaseService;
104 8491 slaughter
import edu.ucsb.nceas.metacat.dataone.SyncAccessPolicy;
105 6447 leinfelder
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
106 8464 leinfelder
import edu.ucsb.nceas.metacat.index.MetacatSolrIndex;
107 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
108 5014 daigle
import edu.ucsb.nceas.metacat.shared.BaseService;
109
import edu.ucsb.nceas.metacat.shared.HandlerException;
110
import edu.ucsb.nceas.metacat.shared.ServiceException;
111 5027 daigle
import edu.ucsb.nceas.metacat.util.DocumentUtil;
112 4698 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
113 6531 leinfelder
import edu.ucsb.nceas.metacat.util.ReplicationUtil;
114 4080 daigle
import edu.ucsb.nceas.metacat.util.SystemUtil;
115 4488 daigle
import edu.ucsb.nceas.utilities.FileUtil;
116 4087 daigle
import edu.ucsb.nceas.utilities.GeneralPropertyException;
117 4080 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
118 7475 leinfelder
import edu.ucsb.nceas.utilities.access.DocInfoHandler;
119
import edu.ucsb.nceas.utilities.access.XMLAccessDAO;
120 4080 daigle
121 5014 daigle
public class ReplicationService extends BaseService {
122 4335 daigle
123 5014 daigle
	private static ReplicationService replicationService = null;
124 2663 sgarg
125 5014 daigle
	private long timeInterval;
126
	private Date firstTime;
127
	private boolean timedReplicationIsOn = false;
128
	Timer replicationDaemon;
129
	private static Vector<String> fileLocks = new Vector<String>();
130
//	private Thread lockThread = null;
131
	public static final String FORCEREPLICATEDELETE = "forcereplicatedelete";
132 7840 leinfelder
	public static final String FORCEREPLICATEDELETEALL = "forcereplicatedeleteall";
133 5014 daigle
	private static String TIMEREPLICATION = "replication.timedreplication";
134
	private static String TIMEREPLICATIONINTERVAl ="replication.timedreplicationinterval";
135
	private static String FIRSTTIME = "replication.firsttimedreplication";
136
	private static final int TIMEINTERVALLIMIT = 7200000;
137
	public static final String REPLICATIONUSER = "replication";
138 7317 leinfelder
139 9206 tao
	//private static RestClient sslClient = null;
140 7317 leinfelder
	private static int CLIENTTIMEOUT = 30000;
141 2286 tao
142 5014 daigle
	public static final String REPLICATION_LOG_FILE_NAME = "metacatreplication.log";
143 7337 leinfelder
144 7356 leinfelder
	private static String DATA_FILE_FLAG = null;
145 5014 daigle
	public static String METACAT_REPL_ERROR_MSG = null;
146
	private static Logger logReplication = Logger.getLogger("ReplicationLogging");
147
	private static Logger logMetacat = Logger.getLogger(ReplicationService.class);
148 2286 tao
149 7317 leinfelder
	static {
150
		// lookup the client timeout
151
		String clientTimeout = null;
152
		try {
153
			clientTimeout = PropertyService.getProperty("replication.client.timeout");
154
			CLIENTTIMEOUT = Integer.parseInt(clientTimeout);
155
		} catch (Exception e) {
156
			// just use default
157
			logReplication.warn("No custom client timeout specified in configuration, using default." + e.getMessage());
158
		}
159 7337 leinfelder
		try {
160
			DATA_FILE_FLAG = PropertyService.getProperty("replication.datafileflag");
161
		} catch (PropertyNotFoundException e) {
162
			logReplication.error("No 'replication.datafileflag' specified in configuration." + e.getMessage());
163
		}
164
165 7317 leinfelder
	}
166
167 5014 daigle
	private ReplicationService() throws ServiceException {
168
		_serviceName = "ReplicationService";
169
170
		initialize();
171
	}
172
173
	private void initialize() throws ServiceException {
174
175
		// initialize db connections to handle any update requests
176
		// deltaT = util.getProperty("replication.deltaT");
177
		// the default deltaT can be set from metacat.properties
178
		// create a thread to do the delta-T check but don't execute it yet
179
		replicationDaemon = new Timer(true);
180
		try {
181
			String replLogFile = PropertyService.getProperty("replication.logdir")
182
				+ FileUtil.getFS() + REPLICATION_LOG_FILE_NAME;
183
			METACAT_REPL_ERROR_MSG = "An error occurred in replication.  Please see the " +
184
				"replication log at: " + replLogFile;
185
186
			String timedRepIsOnStr =
187
				PropertyService.getProperty("replication.timedreplication");
188
			timedReplicationIsOn = (new Boolean(timedRepIsOnStr)).booleanValue();
189
			logReplication.info("ReplicationService.initialize - The timed replication on is" + timedReplicationIsOn);
190 522 berkley
191 5014 daigle
			String timeIntervalStr =
192
				PropertyService.getProperty("replication.timedreplicationinterval");
193
			timeInterval = (new Long(timeIntervalStr)).longValue();
194
			logReplication.info("ReplicationService.initialize - The timed replication time Interval is " + timeInterval);
195 2286 tao
196 5014 daigle
			String firstTimeStr =
197
				PropertyService.getProperty("replication.firsttimedreplication");
198
			logReplication.info("ReplicationService.initialize - first replication time form property is " + firstTimeStr);
199
			firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
200 2286 tao
201 5014 daigle
			logReplication.info("ReplicationService.initialize - After combine current time, the real first time is "
202
					+ firstTime.toString() + " minisec");
203 2286 tao
204 5014 daigle
			// set up time replication if it is on
205
			if (timedReplicationIsOn) {
206
				replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(),
207
						firstTime, timeInterval);
208
				logReplication.info("ReplicationService.initialize - deltaT handler started with rate="
209
						+ timeInterval + " mini seconds at " + firstTime.toString());
210
			}
211 2286 tao
212 5014 daigle
		} catch (PropertyNotFoundException pnfe) {
213
			throw new ServiceException(
214
					"ReplicationService.initialize - Property error while instantiating "
215
							+ "replication service: " + pnfe.getMessage());
216
		} catch (HandlerException he) {
217
			throw new ServiceException(
218
					"ReplicationService.initialize - Handler error while instantiating "
219
							+ "replication service" + he.getMessage());
220
		}
221
	}
222 2286 tao
223 5014 daigle
	/**
224
	 * Get the single instance of SessionService.
225
	 *
226
	 * @return the single instance of SessionService
227
	 */
228
	public static ReplicationService getInstance() throws ServiceException {
229
		if (replicationService == null) {
230
			replicationService = new ReplicationService();
231
		}
232
		return replicationService;
233
	}
234 2286 tao
235 5014 daigle
	public boolean refreshable() {
236
		return true;
237
	}
238 2286 tao
239 5014 daigle
	protected void doRefresh() throws ServiceException {
240
		return;
241
	}
242
243
	public void stop() throws ServiceException{
244
245
	}
246 840 bojilova
247 5014 daigle
	public void stopReplication() throws ServiceException {
248
	      //stop the replication server
249
	      replicationDaemon.cancel();
250
	      replicationDaemon = new Timer(true);
251
	      timedReplicationIsOn = false;
252
	      try {
253
	    	  PropertyService.setProperty("replication.timedreplication", (new Boolean(timedReplicationIsOn)).toString());
254
	      } catch (GeneralPropertyException gpe) {
255
	    	  logReplication.warn("ReplicationService.stopReplication - Could not set replication.timedreplication property: " + gpe.getMessage());
256
	      }
257 4080 daigle
258 5014 daigle
	      logReplication.info("ReplicationService.stopReplication - deltaT handler stopped");
259
		return;
260
	}
261
262 6669 leinfelder
	public void startReplication(Hashtable<String, String[]> params) throws ServiceException {
263 2286 tao
264 5014 daigle
	       String firstTimeStr = "";
265
	      //start the replication server
266
	       if ( params.containsKey("rate") ) {
267
	        timeInterval = new Long(
268
	               new String(((String[])params.get("rate"))[0])).longValue();
269
	        if(timeInterval < TIMEINTERVALLIMIT) {
270
	            //deltaT<30 is a timing mess!
271
	            timeInterval = TIMEINTERVALLIMIT;
272
	            throw new ServiceException("Replication deltaT rate cannot be less than "+
273
	                    TIMEINTERVALLIMIT + " millisecs and system automatically setup the rate to "+TIMEINTERVALLIMIT);
274
	        }
275
	      } else {
276
	        timeInterval = TIMEINTERVALLIMIT ;
277
	      }
278
	      logReplication.info("ReplicationService.startReplication - New rate is: " + timeInterval + " mini seconds.");
279
	      if ( params.containsKey("firsttime"))
280
	      {
281
	         firstTimeStr = ((String[])params.get("firsttime"))[0];
282
	         try
283
	         {
284
	           firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
285
	           logReplication.info("ReplicationService.startReplication - The first time setting is "+firstTime.toString());
286
	         }
287
	         catch (HandlerException e)
288
	         {
289
	            throw new ServiceException(e.getMessage());
290
	         }
291
	         logReplication.warn("After combine current time, the real first time is "
292
	                                  +firstTime.toString()+" minisec");
293
	      }
294
	      else
295
	      {
296
	    	  logMetacat.error("ReplicationService.startReplication - " + ReplicationService.METACAT_REPL_ERROR_MSG);
297
	          logReplication.error("ReplicationService.startReplication - You should specify the first time " +
298
	                                  "to start a time replication");
299
	          return;
300
	      }
301
302
	      timedReplicationIsOn = true;
303
	      try {
304
	      // save settings to property file
305
	      PropertyService.setProperty(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
306
	      // note we couldn't use firstTime object because it has date info
307
	      // we only need time info such as 10:00 PM
308
	      PropertyService.setProperty(FIRSTTIME, firstTimeStr);
309
	      PropertyService.setProperty(TIMEREPLICATIONINTERVAl, (new Long(timeInterval)).toString());
310
	      } catch (GeneralPropertyException gpe) {
311
	    	  logReplication.warn("ReplicationService.startReplication - Could not set property: " + gpe.getMessage());
312
	      }
313
	      replicationDaemon.cancel();
314
	      replicationDaemon = new Timer(true);
315
	      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime,
316
	                                            timeInterval);
317
318
	      logReplication.info("ReplicationService.startReplication - deltaT handler started with rate=" +
319
	                                    timeInterval + " milliseconds at " +firstTime.toString());
320 837 bojilova
321 5014 daigle
	}
322
323
	public void runOnce() throws ServiceException {
324
	      //updates this server exactly once
325
	      replicationDaemon.schedule(new ReplicationHandler(), 0);
326
	}
327 7170 leinfelder
328 5014 daigle
	/**
329
	 * This method can add, delete and list the servers currently included in
330
	 * xml_replication.
331
	 * action           subaction            other needed params
332
	 * ---------------------------------------------------------
333
	 * servercontrol    add                  server
334
	 * servercontrol    delete               server
335
	 * servercontrol    list
336
	 */
337 6669 leinfelder
	public static void handleServerControlRequest(
338 7170 leinfelder
			Hashtable<String, String[]> params, HttpServletRequest request, HttpServletResponse response) {
339 5014 daigle
		String subaction = ((String[]) params.get("subaction"))[0];
340
		DBConnection dbConn = null;
341
		int serialNumber = -1;
342
		PreparedStatement pstmt = null;
343
		String replicate = null;
344
		String server = null;
345
		String dataReplicate = null;
346
		String hub = null;
347 5755 leinfelder
		Writer out = null;
348 8790 leinfelder
		boolean showGenerateSystemMetadata = true;
349 5014 daigle
		try {
350 5755 leinfelder
			response.setContentType("text/xml");
351
			out = response.getWriter();
352
353 5014 daigle
			//conn = util.openDBConnection();
354
			dbConn = DBConnectionPool
355
					.getDBConnection("MetacatReplication.handleServerControlRequest");
356
			serialNumber = dbConn.getCheckOutSerialNumber();
357 837 bojilova
358 5014 daigle
			// add server to server list
359
			if (subaction.equals("add")) {
360
				replicate = ((String[]) params.get("replicate"))[0];
361
				server = ((String[]) params.get("server"))[0];
362 2286 tao
363 5014 daigle
				//Get data replication value
364
				dataReplicate = ((String[]) params.get("datareplicate"))[0];
365 6814 leinfelder
366 5014 daigle
				//Get hub value
367
				hub = ((String[]) params.get("hub"))[0];
368 837 bojilova
369 6595 leinfelder
				Calendar cal = Calendar.getInstance();
370
                cal.set(1980, 1, 1);
371 5151 daigle
				String sql = "INSERT INTO xml_replication "
372 6814 leinfelder
						+ "(server, last_checked, replicate, datareplicate, hub) "
373
						+ "VALUES (?,?,?,?,?)";
374 5151 daigle
375
				pstmt = dbConn.prepareStatement(sql);
376
377
				pstmt.setString(1, server);
378 6595 leinfelder
				pstmt.setTimestamp(2, new Timestamp(cal.getTimeInMillis()));
379
				pstmt.setInt(3, Integer.parseInt(replicate));
380
				pstmt.setInt(4, Integer.parseInt(dataReplicate));
381 6814 leinfelder
				pstmt.setInt(5, Integer.parseInt(hub));
382 5151 daigle
383
				String sqlReport = "XMLAccessAccess.getXMLAccessForDoc - SQL: " + sql;
384
				sqlReport += " [" + server + "," + replicate +
385
					"," + dataReplicate + "," + hub + "]";
386
387
				logMetacat.info(sqlReport);
388
389 5014 daigle
				pstmt.execute();
390
				pstmt.close();
391
				dbConn.commit();
392 5755 leinfelder
				out.write("Server " + server + " added");
393 7170 leinfelder
394
395 5014 daigle
				// delete server from server list
396
			} else if (subaction.equals("delete")) {
397
				server = ((String[]) params.get("server"))[0];
398
				pstmt = dbConn.prepareStatement("DELETE FROM xml_replication "
399 6595 leinfelder
						+ "WHERE server LIKE ?");
400
				pstmt.setString(1, server);
401 5014 daigle
				pstmt.execute();
402
				pstmt.close();
403
				dbConn.commit();
404 5755 leinfelder
				out.write("Server " + server + " deleted");
405 5014 daigle
			} else if (subaction.equals("list")) {
406 7170 leinfelder
				// nothing special - it's the default behavior
407 6135 leinfelder
408 7170 leinfelder
			} else if (subaction.equals("generatesystemmetadata")) {
409
				GenerateSystemMetadata gsm = new GenerateSystemMetadata();
410
				int serverLocation = -1;
411
				String serverid = ((String[]) params.get("serverid"))[0];
412
				serverLocation = Integer.parseInt(serverid);
413
				gsm.setServerLocation(serverLocation );
414
				gsm.multiThreadUpgrade();
415
				out.write("System Metadata generated for server " + serverid);
416
417 7175 leinfelder
			} else if (subaction.equals("generateore")) {
418
				GenerateORE gore = new GenerateORE();
419
				int serverLocation = -1;
420
				String serverid = ((String[]) params.get("serverid"))[0];
421
				serverLocation = Integer.parseInt(serverid);
422
				gore.setServerLocation(serverLocation );
423
				gore.upgrade();
424
				out.write("Generated ORE maps for server " + serverid);
425
426 8746 leinfelder
			} else if (subaction.equals("updatedoi")) {
427
				UpdateDOI udoi = new UpdateDOI();
428
				int serverLocation = -1;
429
				String serverid = ((String[]) params.get("serverid"))[0];
430
				serverLocation = Integer.parseInt(serverid);
431
				udoi.setServerLocation(serverLocation );
432 8760 walker
433
				//Get the list of IDs, if any were given
434
				String ids = ((String[]) params.get("ids"))[0];
435 8746 leinfelder
436 8760 walker
				//Get the formatId, if one was given
437
				String formatIds = ((String[]) params.get("formatIds"))[0];
438
439
				//Allow DOI's to be updated by both ID and formatId
440
				if((ids.length() > 0) || (formatIds.length() > 0)){
441
					//If at least one ID was given, update their DOI registrations
442
					if(ids.length() > 0){
443
						String delimeter = " ";
444
						String[] idArray = ids.split(delimeter);
445
						List<String> idList = Arrays.asList(idArray);
446
						udoi.upgradeById(idList);
447
					}
448
449
					//If at least one formatId was given, update the DOI registrations
450
					if(formatIds.length() > 0){
451
						String delimeter = " ";
452
						String[] formatIdArray = formatIds.split(delimeter);
453
						List<String> formatIdList = Arrays.asList(formatIdArray);
454
						udoi.upgradeByFormatId(formatIdList);
455
					}
456
				}
457
				else{
458
					udoi.upgrade();
459
				}
460
				out.write("Updated DOI's for server " + serverid);
461
462 7519 leinfelder
			} else if (subaction.equals("removeinvalidreplicas")) {
463
				RemoveInvalidReplicas rir = new RemoveInvalidReplicas();
464
				int serverLocation = -1;
465
				String serverid = ((String[]) params.get("serverid"))[0];
466
				serverLocation = Integer.parseInt(serverid);
467
				rir.setServerLocation(serverLocation );
468
				rir.upgrade();
469
				out.write("Removed invalid replicas for server " + serverid);
470
471 8491 slaughter
			} else if (subaction.equals("syncaccesspolicy")) {
472
				SyncAccessPolicy syncAP = new SyncAccessPolicy();
473
				response.setContentType("text/html");
474
				out = response.getWriter();
475 8585 leinfelder
				if (params.containsKey("pid")) {
476
					String[] pids = params.get("pid");
477
					logMetacat.debug("Attempting to sync access policies for pids: " + pids);
478
					ArrayList<String> pidsToSync = new ArrayList<String>(Arrays.asList(pids));
479 8491 slaughter
					try {
480 8585 leinfelder
						List<Identifier> syncedPids = syncAP.sync(pidsToSync);
481
						out.write("<html><body>Syncing access policies has completed for " + syncedPids.size() + " pids.</body></html>");
482 8491 slaughter
					} catch (Exception e) {
483
						logMetacat.error("Error syncing all access polies: "
484
								+ e.getMessage());
485
						response.setContentType("text/html");
486
						out = response.getWriter();
487
						out.write("<html><body>Error syncing access policies</body></html>");
488
					}
489
				} else {
490 8590 slaughter
					logMetacat.debug("Request to sync all access policies has been submitted.");
491 8491 slaughter
					try {
492
						syncAP.syncAll();
493 8590 slaughter
						out.write("<html><body>Request to sync all access policies has been submitted.</body></html>");
494 8491 slaughter
					} catch (Exception e) {
495
						logMetacat.error("Error syncing access policies: "
496
								+ e.getMessage());
497
						out.write("<html><body>Error syncing access policies: " + e.getMessage() + " </body></html>");
498
					}
499
				}
500 5014 daigle
			} else {
501 7170 leinfelder
502 5755 leinfelder
				out.write("<error>Unkonwn subaction</error>");
503 7170 leinfelder
				return;
504
			}
505
506 8790 leinfelder
			// hide SM/ORE buttons?
507
//			String dataoneConfigured = PropertyService.getProperty("configutil.dataoneConfigured");
508
//			if (dataoneConfigured != null) {
509
//				showGenerateSystemMetadata = Boolean.parseBoolean(dataoneConfigured);
510
//			}
511 7170 leinfelder
512
			// always list them after processing
513
			response.setContentType("text/html");
514
			out.write("<html><body><table border=\"1\">");
515
			out.write("<tr><td><b>server</b></td>");
516
			out.write("<td><b>last_checked</b></td>");
517
			out.write("<td><b>replicate</b></td>");
518
			out.write("<td><b>datareplicate</b></td>");
519
			out.write("<td><b>hub</b></td>");
520
			if (showGenerateSystemMetadata) {
521 7175 leinfelder
				out.write("<td><b>System Metadata</b></td>");
522
				out.write("<td><b>ORE Maps</b></td>");
523 8746 leinfelder
				out.write("<td><b>DOI Registrations</b></td>");
524 7519 leinfelder
				out.write("<td><b>Invalid Replicas</b></td>");
525 7170 leinfelder
			}
526 8491 slaughter
			out.write("<td><b>Sync Access Policies</b></td>");
527 7170 leinfelder
			out.write("</tr>");
528 2286 tao
529 7170 leinfelder
			pstmt = dbConn.prepareStatement("SELECT serverid, server, last_checked, replicate, datareplicate, hub FROM xml_replication");
530
			pstmt.execute();
531
			ResultSet rs = pstmt.getResultSet();
532
			boolean tablehasrows = rs.next();
533
			while (tablehasrows) {
534 7519 leinfelder
				String serverId = rs.getString(1);
535 7170 leinfelder
				out.write("<tr><td>" + rs.getString(2) + "</td><td>");
536
				out.write(rs.getString(3) + "</td><td>");
537
				out.write(rs.getString(4) + "</td><td>");
538
				out.write(rs.getString(5) + "</td><td>");
539
				out.write(rs.getString(6) + "</td>");
540
				if (showGenerateSystemMetadata) {
541 7175 leinfelder
					// for SM
542 7170 leinfelder
					out.write("<td><form action='" + request.getContextPath() + "/admin'>");
543 7519 leinfelder
					out.write("<input name='serverid' type='hidden' value='" + serverId  + "'/>");
544 7170 leinfelder
					out.write("<input name='configureType' type='hidden' value='replication'/>");
545
					out.write("<input name='action' type='hidden' value='servercontrol'/>");
546
					out.write("<input name='subaction' type='hidden' value='generatesystemmetadata'/>");
547
					out.write("<input type='submit' value='Generate System Metadata'/>");
548
					out.write("</form></td>");
549 7175 leinfelder
550
					// for ORE maps
551
					out.write("<td><form action='" + request.getContextPath() + "/admin'>");
552 7519 leinfelder
					out.write("<input name='serverid' type='hidden' value='" + serverId + "'/>");
553 7175 leinfelder
					out.write("<input name='configureType' type='hidden' value='replication'/>");
554
					out.write("<input name='action' type='hidden' value='servercontrol'/>");
555
					out.write("<input name='subaction' type='hidden' value='generateore'/>");
556
					out.write("<input type='submit' value='Generate ORE'/>");
557
					out.write("</form></td>");
558 7519 leinfelder
559 8746 leinfelder
					// for DOI updating
560
					out.write("<td><form action='" + request.getContextPath() + "/admin'>");
561
					out.write("<input name='serverid' type='hidden' value='" + serverId + "'/>");
562
					out.write("<input name='configureType' type='hidden' value='replication'/>");
563
					out.write("<input name='action' type='hidden' value='servercontrol'/>");
564
					out.write("<input name='subaction' type='hidden' value='updatedoi'/>");
565 8760 walker
					out.write("<label>Update by ID:</label>");
566
					out.write("<textarea name='ids'></textarea>");
567
					out.write("<label>Update by formatId:</label>");
568
					out.write("<textarea name='formatIds'></textarea>");
569 8746 leinfelder
					out.write("<input type='submit' value='Update DOIs'/>");
570
					out.write("</form></td>");
571
572 7519 leinfelder
					// for invalid replicas
573
					out.write("<td><form action='" + request.getContextPath() + "/admin'>");
574
					out.write("<input name='serverid' type='hidden' value='" + serverId + "'/>");
575
					out.write("<input name='configureType' type='hidden' value='replication'/>");
576
					out.write("<input name='action' type='hidden' value='servercontrol'/>");
577
					out.write("<input name='subaction' type='hidden' value='removeinvalidreplicas'/>");
578
					String disabled = "";
579
					if (Integer.valueOf(serverId) == 1) {
580
						disabled = "disabled='true'";
581
					}
582
					out.write("<input type='submit' value='Remove Invalid Replicas' " + disabled + " />");
583
					out.write("</form></td>");
584 7170 leinfelder
				}
585 8491 slaughter
				// for syncing access policies (MN -> CN)
586
				out.write("<td><form action='" + request.getContextPath() + "/admin'>");
587
				out.write("<input name='serverid' type='hidden' value='" + serverId + "'/>");
588
				out.write("<input name='configureType' type='hidden' value='replication'/>");
589
				out.write("<input name='action' type='hidden' value='servercontrol'/>");
590
				out.write("<input name='subaction' type='hidden' value='syncaccesspolicy'/>");
591
				out.write("<input type='submit' value='Sync access policies'/>");
592
				out.write("</form></td>");
593
594 7170 leinfelder
				out.write("</tr>");
595
596
				tablehasrows = rs.next();
597 5014 daigle
			}
598 7170 leinfelder
			out.write("</table></body></html>");
599
600
601 5014 daigle
			pstmt.close();
602
			//conn.close();
603 2286 tao
604 5014 daigle
		} catch (Exception e) {
605
			logMetacat.error("ReplicationService.handleServerControlRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
606
			logReplication.error("ReplicationService.handleServerControlRequest - Error in "
607
					+ "MetacatReplication.handleServerControlRequest " + e.getMessage());
608
			e.printStackTrace(System.out);
609
		} finally {
610
			try {
611
				pstmt.close();
612
			}//try
613
			catch (SQLException ee) {
614
				logMetacat.error("ReplicationService.handleServerControlRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
615
				logReplication.error("ReplicationService.handleServerControlRequest - Error in MetacatReplication.handleServerControlRequest to close pstmt "
616
						+ ee.getMessage());
617
			}//catch
618
			finally {
619
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
620
			}//finally
621 5755 leinfelder
			if (out != null) {
622
				try {
623
					out.close();
624
				} catch (IOException e) {
625
					logMetacat.error(e.getMessage(), e);
626
				}
627
			}
628 5014 daigle
		}//finally
629 2286 tao
630 5014 daigle
	}
631 2286 tao
632 5014 daigle
	/**
633 4080 daigle
	 * when a forcereplication request comes in, local host sends a read request
634
	 * to the requesting server (remote server) for the specified docid. Then
635
	 * store it in local database.
636
	 */
637 5755 leinfelder
	protected static void handleForceReplicateRequest(
638 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
639
			HttpServletRequest request) {
640
		String server = ((String[]) params.get("server"))[0]; // the server that
641
		String docid = ((String[]) params.get("docid"))[0]; // sent the document
642
		String dbaction = "UPDATE"; // the default action is UPDATE
643
		//    boolean override = false;
644
		//    int serverCode = 1;
645
		DBConnection dbConn = null;
646
		int serialNumber = -1;
647 5459 berkley
		String docName = null;
648 2286 tao
649 5014 daigle
		try {
650
			//if the url contains a dbaction then the default action is overridden
651
			if (params.containsKey("dbaction")) {
652
				dbaction = ((String[]) params.get("dbaction"))[0];
653
				//serverCode = MetacatReplication.getServerCode(server);
654
				//override = true; //we are now overriding the default action
655
			}
656
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication request from: " + server);
657
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication docid: " + docid);
658
			logReplication.info("ReplicationService.handleForceReplicateRequest - Force replication action: " + dbaction);
659
			// sending back read request to remote server
660
			URL u = new URL("https://" + server + "?server="
661
					+ MetacatUtil.getLocalReplicationServerName() + "&action=read&docid="
662
					+ docid);
663 8959 tao
			byte[] xmlBytes = ReplicationService.getURLBytes(u);
664
            String xmldoc = new String(xmlBytes, "UTF-8");
665 2286 tao
666 5014 daigle
			// get the document info from server
667
			URL docinfourl = new URL("https://" + server + "?server="
668
					+ MetacatUtil.getLocalReplicationServerName()
669
					+ "&action=getdocumentinfo&docid=" + docid);
670 5440 berkley
671 2286 tao
672 5014 daigle
			String docInfoStr = ReplicationService.getURLContent(docinfourl);
673 6531 leinfelder
			// strip out the system metadata portion
674
			String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
675
			docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
676
677 5014 daigle
			//dih is the parser for the docinfo xml format
678
			DocInfoHandler dih = new DocInfoHandler();
679
			XMLReader docinfoParser = ReplicationHandler.initParser(dih);
680
			docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
681
			//      Hashtable<String,Vector<AccessControlForSingleFile>> docinfoHash = dih.getDocInfo();
682
			Hashtable<String, String> docinfoHash = dih.getDocInfo();
683 6015 leinfelder
684 5014 daigle
			// Get home server of this docid
685
			String homeServer = (String) docinfoHash.get("home_server");
686 6531 leinfelder
687
			// process system metadata
688 8739 tao
			SystemMetadata sysMeta = null;
689 6531 leinfelder
			if (systemMetadataXML != null) {
690 8739 tao
				sysMeta =
691 6531 leinfelder
					TypeMarshaller.unmarshalTypeFromStream(
692
							SystemMetadata.class,
693
							new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
694
				// need the guid-to-docid mapping
695 6783 leinfelder
				boolean mappingExists = true;
696 7045 leinfelder
		      	mappingExists = IdentifierManager.getInstance().mappingExists(sysMeta.getIdentifier().getValue());
697 6783 leinfelder
		      	if (!mappingExists) {
698
		      		IdentifierManager.getInstance().createMapping(sysMeta.getIdentifier().getValue(), docid);
699
		      	}
700 6666 leinfelder
				// save the system metadata
701
				HazelcastService.getInstance().getSystemMetadataMap().put(sysMeta.getIdentifier(), sysMeta);
702 8739 tao
703 6531 leinfelder
			}
704 5324 berkley
705 6595 leinfelder
			// dates
706
			String createdDateString = docinfoHash.get("date_created");
707
			String updatedDateString = docinfoHash.get("date_updated");
708 6614 leinfelder
			Date createdDate = DateTimeMarshaller.deserializeDateToUTC(createdDateString);
709
			Date updatedDate = DateTimeMarshaller.deserializeDateToUTC(updatedDateString);
710 6595 leinfelder
711 5014 daigle
			logReplication.info("ReplicationService.handleForceReplicateRequest - homeServer: " + homeServer);
712
			// Get Document type
713
			String docType = (String) docinfoHash.get("doctype");
714
			logReplication.info("ReplicationService.handleForceReplicateRequest - docType: " + docType);
715
			String parserBase = null;
716
			// this for eml2 and we need user eml2 parser
717
			if (docType != null
718
					&& (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE)) {
719
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml200 document!");
720
				parserBase = DocumentImpl.EML200;
721
			} else if (docType != null
722
					&& (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE)) {
723
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.0.1 document!");
724
				parserBase = DocumentImpl.EML200;
725
			} else if (docType != null
726
					&& (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE)) {
727
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.1.0 document!");
728
				parserBase = DocumentImpl.EML210;
729 5709 leinfelder
			} else if (docType != null
730
					&& (docType.trim()).equals(DocumentImpl.EML2_1_1NAMESPACE)) {
731
				logReplication.warn("ReplicationService.handleForceReplicateRequest - This is an eml2.1.1 document!");
732
				parserBase = DocumentImpl.EML210;
733 5014 daigle
			}
734
			logReplication.warn("ReplicationService.handleForceReplicateRequest - The parserBase is: " + parserBase);
735 9583 tao
736 9958 tao
			/*String formatId = null;
737 9583 tao
		    //get the format id from the system metadata
738
		    if(sysMeta != null && sysMeta.getFormatId() != null) {
739
		          logMetacat.debug("ReplicationService.handleForceReplicateRequest - the format id will be got from the system metadata for the object "+docid);
740
		          formatId = sysMeta.getFormatId().getValue();
741 9958 tao
		    }*/
742 9583 tao
743 5014 daigle
			// Get DBConnection from pool
744
			dbConn = DBConnectionPool
745
					.getDBConnection("MetacatReplication.handleForceReplicateRequest");
746
			serialNumber = dbConn.getCheckOutSerialNumber();
747
			// write the document to local database
748 7128 leinfelder
			DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false, false);
749 6079 leinfelder
			//try this independently so we can set access even if the update action is invalid (i.e docid has not changed)
750 5014 daigle
			try {
751 8959 tao
				wrapper.writeReplication(dbConn, xmldoc, xmlBytes, null, null,
752 6015 leinfelder
						dbaction, docid, null, null, homeServer, server, createdDate,
753 9958 tao
						updatedDate);
754 5195 daigle
			} finally {
755 8739 tao
				if(sysMeta != null) {
756
					// submit for indexing. When the doc writing process fails, the index process will fail as well. But this failure
757
					// will not interrupt the process.
758
					try {
759
						MetacatSolrIndex.getInstance().submit(sysMeta.getIdentifier(), sysMeta, null, true);
760
					} catch (Exception ee) {
761
						logReplication.warn("ReplicationService.handleForceReplicateRequest - couldn't index the doc since "+ee.getMessage());
762
					}
763
764
				}
765 7358 leinfelder
				//process extra access rules before dealing with the write exception (doc exist already)
766
				try {
767
		        	// check if we had a guid -> docid mapping
768
		        	String docidNoRev = DocumentUtil.getDocIdFromAccessionNumber(docid);
769
		        	int rev = DocumentUtil.getRevisionFromAccessionNumber(docid);
770 7382 leinfelder
		        	IdentifierManager.getInstance().getGUID(docidNoRev, rev);
771 7358 leinfelder
		        	// no need to create the mapping if we have it
772
		        } catch (McdbDocNotFoundException mcdbe) {
773
		        	// create mapping if we don't
774
		        	IdentifierManager.getInstance().createMapping(docid, docid);
775
		        }
776 5195 daigle
		        Vector<XMLAccessDAO> accessControlList = dih.getAccessControlList();
777
		        if (accessControlList != null) {
778
		        	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
779
		        	for (XMLAccessDAO xmlAccessDAO : accessControlList) {
780 7120 leinfelder
		        		try {
781
			        		if (!acfsf.accessControlExists(xmlAccessDAO)) {
782
			        			acfsf.insertPermissions(xmlAccessDAO);
783
								logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid
784
										+ " permissions added to DB");
785
			        		}
786
		        		} catch (PermOrderException poe) {
787
		        			// this is problematic, but should not prevent us from replicating
788
		        			// see https://redmine.dataone.org/issues/2583
789
		        			String msg = "Could not insert access control for: " + docid + " Message: " + poe.getMessage();
790
		        			logMetacat.error(msg, poe);
791
		        			logReplication.error(msg, poe);
792 5195 daigle
		        		}
793
		            }
794
		        }
795 6015 leinfelder
796
		        // process the real owner and updater
797
				String user = (String) docinfoHash.get("user_owner");
798
				String updated = (String) docinfoHash.get("user_updated");
799
		        updateUserOwner(dbConn, docid, user, updated);
800 2286 tao
801 5195 daigle
				logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid + " added to DB with "
802
						+ "action " + dbaction);
803 5458 berkley
804 6542 leinfelder
				EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), REPLICATIONUSER, docid, dbaction);
805 5014 daigle
			}
806 5195 daigle
		} catch (SQLException sqle) {
807 5014 daigle
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
808 5195 daigle
			logReplication.error("ReplicationService.handleForceReplicateRequest - SQL error when adding doc " + docid +
809
					" to DB with action " + dbaction + ": " + sqle.getMessage());
810
		} catch (MalformedURLException mue) {
811
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
812
			logReplication.error("ReplicationService.handleForceReplicateRequest - URL error when adding doc " + docid +
813
					" to DB with action " + dbaction + ": " + mue.getMessage());
814
		} catch (SAXException se) {
815
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
816
			logReplication.error("ReplicationService.handleForceReplicateRequest - SAX parsing error when adding doc " + docid +
817
					" to DB with action " + dbaction + ": " + se.getMessage());
818
		} catch (HandlerException he) {
819
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
820
			logReplication.error("ReplicationService.handleForceReplicateRequest - Handler error when adding doc " + docid +
821
					" to DB with action " + dbaction + ": " + he.getMessage());
822
		} catch (IOException ioe) {
823
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
824
			logReplication.error("ReplicationService.handleForceReplicateRequest - I/O error when adding doc " + docid +
825
					" to DB with action " + dbaction + ": " + ioe.getMessage());
826
		} catch (PermOrderException poe) {
827
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
828
			logReplication.error("ReplicationService.handleForceReplicateRequest - Permissions order error when adding doc " + docid +
829
					" to DB with action " + dbaction + ": " + poe.getMessage());
830
		} catch (AccessControlException ace) {
831
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
832
			logReplication.error("ReplicationService.handleForceReplicateRequest - Permissions order error when adding doc " + docid +
833
					" to DB with action " + dbaction + ": " + ace.getMessage());
834
		} catch (Exception e) {
835
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
836
			logReplication.error("ReplicationService.handleForceReplicateRequest - General error when adding doc " + docid +
837
					" to DB with action " + dbaction + ": " + e.getMessage());
838
		} finally {
839 5014 daigle
			// Return the checked out DBConnection
840
			DBConnectionPool.returnDBConnection(dbConn, serialNumber);
841
		}//finally
842
	}
843 2298 tao
844 5014 daigle
	/*
845
	 * when a forcereplication delete request comes in, local host will delete this
846
	 * document
847
	 */
848 5755 leinfelder
	protected static void handleForceReplicateDeleteRequest(
849 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
850 7840 leinfelder
			HttpServletRequest request, boolean removeAll) {
851 5014 daigle
		String server = ((String[]) params.get("server"))[0]; // the server that
852
		String docid = ((String[]) params.get("docid"))[0]; // sent the document
853
		try {
854
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - force replication delete request from " + server);
855
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - force replication delete docid " + docid);
856
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - Force replication delete request from: " + server);
857
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - Force replication delete docid: " + docid);
858 7840 leinfelder
			DocumentImpl.delete(docid, null, null, server, removeAll);
859 5014 daigle
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - document " + docid + " was successfully deleted ");
860 6542 leinfelder
			EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), REPLICATIONUSER, docid,
861 5014 daigle
					"delete");
862
			logReplication.info("ReplicationService.handleForceReplicateDeleteRequest - document " + docid + " was successfully deleted ");
863 6001 cjones
		} catch (McdbDocNotFoundException e) {
864
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
865
			logReplication.error("document " + docid
866
					+ " failed to delete because " + e.getMessage());
867
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
868
		} catch (InsufficientKarmaException e) {
869
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
870
			logReplication.error("document " + docid
871
					+ " failed to delete because " + e.getMessage());
872
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
873
		} catch (SQLException e) {
874
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
875
			logReplication.error("document " + docid
876
					+ " failed to delete because " + e.getMessage());
877
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
878 5014 daigle
		} catch (Exception e) {
879
			logMetacat.error("ReplicationService.handleForceReplicateDeleteRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
880
			logReplication.error("document " + docid
881
					+ " failed to delete because " + e.getMessage());
882
			logReplication.error("ReplicationService.handleForceReplicateDeleteRequest - error: " + e.getMessage());
883 2298 tao
884 5014 daigle
		}//catch
885 2298 tao
886 5014 daigle
	}
887 2286 tao
888 5014 daigle
	/**
889
	 * when a forcereplication data file request comes in, local host sends a
890
	 * readdata request to the requesting server (remote server) for the specified
891
	 * docid. Then store it in local database and file system
892
	 */
893
	protected static void handleForceReplicateDataFileRequest(Hashtable<String, String[]> params,
894
			HttpServletRequest request) {
895 2286 tao
896 5014 daigle
		//make sure there is some parameters
897
		if (params.isEmpty()) {
898
			return;
899
		}
900
		// Get remote server
901
		String server = ((String[]) params.get("server"))[0];
902
		// the docid should include rev number
903
		String docid = ((String[]) params.get("docid"))[0];
904
		// Make sure there is a docid and server
905
		if (docid == null || server == null || server.equals("")) {
906
			logMetacat.error("ReplicationService.handleForceReplicateDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
907
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - Didn't specify docid or server for replication");
908
			return;
909
		}
910 2286 tao
911 5014 daigle
		// Overide or not
912
		//    boolean override = false;
913
		// dbaction - update or insert
914
		String dbaction = null;
915 2286 tao
916 5014 daigle
		try {
917
			//docid was switch to two parts uinque code and rev
918
			//String uniqueCode=MetacatUtil.getDocIdFromString(docid);
919
			//int rev=MetacatUtil.getVersionFromString(docid);
920
			if (params.containsKey("dbaction")) {
921
				dbaction = ((String[]) params.get("dbaction"))[0];
922
			} else//default value is update
923
			{
924 6782 leinfelder
//				dbaction = "update";
925
				dbaction = null;
926 5014 daigle
			}
927 2286 tao
928 5014 daigle
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication request from: " + server);
929
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication docid: " + docid);
930
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - Force replication action: " + dbaction);
931
			// get the document info from server
932
			URL docinfourl = new URL("https://" + server + "?server="
933
					+ MetacatUtil.getLocalReplicationServerName()
934
					+ "&action=getdocumentinfo&docid=" + docid);
935 1023 tao
936 5014 daigle
			String docInfoStr = ReplicationService.getURLContent(docinfourl);
937 6102 leinfelder
938 6531 leinfelder
			// strip out the system metadata portion
939
		    String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
940
		   	docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
941
942 5014 daigle
			//dih is the parser for the docinfo xml format
943
			DocInfoHandler dih = new DocInfoHandler();
944
			XMLReader docinfoParser = ReplicationHandler.initParser(dih);
945
			docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
946
			Hashtable<String, String> docinfoHash = dih.getDocInfo();
947 6015 leinfelder
948 5014 daigle
			String docName = (String) docinfoHash.get("docname");
949 2286 tao
950 5014 daigle
			String docType = (String) docinfoHash.get("doctype");
951 2286 tao
952 5014 daigle
			String docHomeServer = (String) docinfoHash.get("home_server");
953 6595 leinfelder
954
			String createdDateString = docinfoHash.get("date_created");
955
			String updatedDateString = docinfoHash.get("date_updated");
956
957 6614 leinfelder
			Date createdDate = DateTimeMarshaller.deserializeDateToUTC(createdDateString);
958
			Date updatedDate = DateTimeMarshaller.deserializeDateToUTC(updatedDateString);
959 6595 leinfelder
960 5014 daigle
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - docHomeServer of datafile: " + docHomeServer);
961
962 6782 leinfelder
			// in case we have a write exception, we still want to track access and sysmeta
963
			Exception writeException = null;
964
965
			// do we need the object content?
966
			if (dbaction != null && (dbaction.equals("insert") || dbaction.equals("update"))) {
967 5014 daigle
				//Get data file and store it into local file system.
968
				// sending back readdata request to server
969
				URL url = new URL("https://" + server + "?server="
970
						+ MetacatUtil.getLocalReplicationServerName()
971
						+ "&action=readdata&docid=" + docid);
972
				String datafilePath = PropertyService
973
						.getProperty("application.datafilepath");
974
975 6611 leinfelder
976 9206 tao
977 6780 leinfelder
				//register data file into xml_documents table and write data file
978 5014 daigle
				//into file system
979 9206 tao
				InputStream inputStream = null;
980 5014 daigle
				try {
981 9206 tao
				    inputStream = getURLStream(url);
982 6611 leinfelder
					DocumentImpl.writeDataFileInReplication(inputStream,
983 6015 leinfelder
							datafilePath, docName, docType, docid, null, docHomeServer,
984 5014 daigle
							server, DocumentImpl.DOCUMENTTABLE, false, createdDate,
985
							updatedDate);
986
				} catch (Exception e) {
987
					writeException = e;
988 9204 rnahf
				} finally {
989
				    IOUtils.closeQuietly(inputStream);
990 5014 daigle
				}
991
992
			}
993 6782 leinfelder
994
			// process the real owner and updater
995
			DBConnection dbConn = DBConnectionPool.getDBConnection("ReplicationService.handleForceDataFileRequest");
996
	        int serialNumber = dbConn.getCheckOutSerialNumber();
997
	        dbConn.setAutoCommit(false);
998
			String user = (String) docinfoHash.get("user_owner");
999
			String updated = (String) docinfoHash.get("user_updated");
1000
	        updateUserOwner(dbConn, docid, user, updated);
1001
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1002
1003
			// process system metadata
1004
	        if (systemMetadataXML != null) {
1005
	      	  SystemMetadata sysMeta =
1006
	      		TypeMarshaller.unmarshalTypeFromStream(
1007
	      				  SystemMetadata.class,
1008
	      				  new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
1009
1010
	      	  // need the guid-to-docid mapping
1011
	      	  boolean mappingExists = true;
1012 7045 leinfelder
	      	  mappingExists = IdentifierManager.getInstance().mappingExists(sysMeta.getIdentifier().getValue());
1013 6782 leinfelder
	      	  if (!mappingExists) {
1014
	      		  IdentifierManager.getInstance().createMapping(sysMeta.getIdentifier().getValue(), docid);
1015
	      	  }
1016
	      	  // save the system metadata
1017
	      	  HazelcastService.getInstance().getSystemMetadataMap().put(sysMeta.getIdentifier(), sysMeta);
1018 7812 leinfelder
	      	  // submit for indexing
1019 8647 leinfelder
              MetacatSolrIndex.getInstance().submit(sysMeta.getIdentifier(), sysMeta, null, true);
1020 6782 leinfelder
	        }
1021
1022
	        // process the access control
1023 7358 leinfelder
	        try {
1024
	        	// check if we had a guid -> docid mapping
1025
	        	String docidNoRev = DocumentUtil.getDocIdFromAccessionNumber(docid);
1026 7382 leinfelder
	        	int rev = DocumentUtil.getRevisionFromAccessionNumber(docid);
1027
	        	IdentifierManager.getInstance().getGUID(docidNoRev, rev);
1028 7358 leinfelder
	        	// no need to create the mapping if we have it
1029
	        } catch (McdbDocNotFoundException mcdbe) {
1030
	        	// create mapping if we don't
1031
	        	IdentifierManager.getInstance().createMapping(docid, docid);
1032
	        }
1033 6782 leinfelder
	        Vector<XMLAccessDAO> accessControlList = dih.getAccessControlList();
1034
	        if (accessControlList != null) {
1035
	        	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
1036
	        	for (XMLAccessDAO xmlAccessDAO : accessControlList) {
1037
	        		if (!acfsf.accessControlExists(xmlAccessDAO)) {
1038
	        			acfsf.insertPermissions(xmlAccessDAO);
1039
						logReplication.info("ReplicationService.handleForceReplicateRequest - document " + docid
1040
								+ " permissions added to DB");
1041
	        		}
1042
	            }
1043
	        }
1044
1045
	        // throw the write exception now -- this happens when access changes on an object
1046
			if (writeException != null) {
1047
				throw writeException;
1048
			}
1049 5014 daigle
1050 6782 leinfelder
			logReplication.info("ReplicationService.handleForceReplicateDataFileRequest - datafile " + docid + " added to DB with "
1051
					+ "action " + dbaction);
1052
			EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), REPLICATIONUSER,
1053
					docid, dbaction);
1054
1055 5014 daigle
		} catch (Exception e) {
1056 6613 leinfelder
			e.printStackTrace();
1057
			logMetacat.error("ReplicationService.handleForceReplicateDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG, e);
1058 5014 daigle
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - Datafile " + docid
1059
					+ " failed to added to DB with " + "action " + dbaction + " because "
1060
					+ e.getMessage());
1061
			logReplication.error("ReplicationService.handleForceReplicateDataFileRequest - ERROR in MetacatReplication.handleForceDataFileReplicate"
1062
					+ "Request(): " + e.getMessage());
1063 4449 leinfelder
		}
1064 5014 daigle
	}
1065 2286 tao
1066 5014 daigle
	/**
1067
	 * Grants or denies a lock to a requesting host.
1068
	 * The servlet parameters of interrest are:
1069
	 * docid: the docid of the file the lock is being requested for
1070
	 * currentdate: the timestamp of the document on the remote server
1071
	 *
1072
	 */
1073 5755 leinfelder
	protected static void handleGetLockRequest(
1074 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1075 1292 tao
1076 5014 daigle
		try {
1077 2286 tao
1078 5014 daigle
			String docid = ((String[]) params.get("docid"))[0];
1079
			String remoteRev = ((String[]) params.get("updaterev"))[0];
1080
			DocumentImpl requestDoc = new DocumentImpl(docid);
1081
			logReplication.info("ReplicationService.handleGetLockRequest - lock request for " + docid);
1082
			int localRevInt = requestDoc.getRev();
1083
			int remoteRevInt = Integer.parseInt(remoteRev);
1084 2286 tao
1085 5755 leinfelder
			// get a writer for sending back to response
1086
			response.setContentType("text/xml");
1087
			Writer out = response.getWriter();
1088
1089 5014 daigle
			if (remoteRevInt >= localRevInt) {
1090
				if (!fileLocks.contains(docid)) { //grant the lock if it is not already locked
1091
					fileLocks.add(0, docid); //insert at the beginning of the queue Vector
1092
					//send a message back to the the remote host authorizing the insert
1093 5755 leinfelder
					out.write("<lockgranted><docid>" + docid
1094 5014 daigle
									+ "</docid></lockgranted>");
1095
					//          lockThread = new Thread(this);
1096
					//          lockThread.setPriority(Thread.MIN_PRIORITY);
1097
					//          lockThread.start();
1098
					logReplication.info("ReplicationService.handleGetLockRequest - lock granted for " + docid);
1099
				} else { //deny the lock
1100 5755 leinfelder
					out.write("<filelocked><docid>" + docid + "</docid></filelocked>");
1101 5014 daigle
					logReplication.info("ReplicationService.handleGetLockRequest - lock denied for " + docid
1102
							+ "reason: file already locked");
1103
				}
1104
			} else {//deny the lock.
1105 5755 leinfelder
				out.write("<outdatedfile><docid>" + docid + "</docid></filelocked>");
1106 5014 daigle
				logReplication.info("ReplicationService.handleGetLockRequest - lock denied for " + docid
1107
						+ "reason: client has outdated file");
1108
			}
1109 5755 leinfelder
			out.close();
1110 5014 daigle
			//conn.close();
1111
		} catch (Exception e) {
1112
			logMetacat.error("ReplicationService.handleGetLockRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1113
			logReplication.error("ReplicationService.handleGetLockRequest - error requesting file lock from MetacatReplication."
1114
					+ "handleGetLockRequest: " + e.getMessage());
1115
			e.printStackTrace(System.out);
1116
		}
1117
	}
1118 2286 tao
1119 5014 daigle
	/**
1120
	 * Sends all of the xml_documents information encoded in xml to a requestor
1121
	 * the format is:
1122
	 * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
1123
	 *                  user_updated, home_server, public_access, rev)/>
1124
	 * all of the subelements of document info are #PCDATA
1125
	 */
1126 5755 leinfelder
	protected static void handleGetDocumentInfoRequest(
1127 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1128
		String docid = ((String[]) (params.get("docid")))[0];
1129 2286 tao
1130 5014 daigle
		try {
1131 6708 leinfelder
			// get docinfo as XML string
1132
			String docinfoXML = getDocumentInfo(docid);
1133 6531 leinfelder
1134 5755 leinfelder
			// get a writer for sending back to response
1135 5014 daigle
			response.setContentType("text/xml");
1136 5755 leinfelder
			Writer out = response.getWriter();
1137 6708 leinfelder
			out.write(docinfoXML);
1138 5755 leinfelder
			out.close();
1139 2286 tao
1140 5014 daigle
		} catch (Exception e) {
1141
			logMetacat.error("ReplicationService.handleGetDocumentInfoRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1142
			logReplication.error("ReplicationService.handleGetDocumentInfoRequest - error in metacatReplication.handlegetdocumentinforequest "
1143
					+ "for doc: " + docid + " : " + e.getMessage());
1144
		}
1145 2286 tao
1146 5014 daigle
	}
1147 6118 leinfelder
1148 6708 leinfelder
	public static Hashtable<String, String> getDocumentInfoMap(String docid)
1149 9833 tao
			throws HandlerException, AccessControlException, MarshallingException,
1150 6708 leinfelder
			IOException, McdbException, SAXException {
1151
1152
		// Try get docid info from remote server
1153
		DocInfoHandler dih = new DocInfoHandler();
1154
		XMLReader docinfoParser = ReplicationHandler.initParser(dih);
1155
1156
		String docInfoStr = getDocumentInfo(docid);
1157
1158
		// strip out the system metadata portion
1159
		String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
1160
		docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
1161
1162
		docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
1163
		Hashtable<String, String> docinfoHash = dih.getDocInfo();
1164
1165
		return docinfoHash;
1166
	}
1167
1168 6118 leinfelder
	/**
1169 6708 leinfelder
	 * Gets a docInfo XML snippet for the replication API
1170
	 * @param docid
1171
	 * @return
1172
	 * @throws AccessControlException
1173
	 * @throws JiBXException
1174
	 * @throws IOException
1175
	 * @throws McdbException
1176
	 */
1177 9833 tao
	public static String getDocumentInfo(String docid) throws AccessControlException, MarshallingException, IOException, McdbException {
1178 6708 leinfelder
		StringBuffer sb = new StringBuffer();
1179
1180
		DocumentImpl doc = new DocumentImpl(docid);
1181
		sb.append("<documentinfo><docid>").append(docid);
1182
		sb.append("</docid>");
1183
1184
		try {
1185
			// serialize the System Metadata as XML for docinfo
1186
			String guid = IdentifierManager.getInstance().getGUID(doc.getDocID(), doc.getRev());
1187
			SystemMetadata systemMetadata = IdentifierManager.getInstance().getSystemMetadata(guid);
1188
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
1189
			TypeMarshaller.marshalTypeToOutputStream(systemMetadata, baos);
1190
			String systemMetadataXML = baos.toString("UTF-8");
1191
			sb.append("<systemMetadata>");
1192
			sb.append(systemMetadataXML);
1193
			sb.append("</systemMetadata>");
1194
		} catch(McdbDocNotFoundException e) {
1195
		  logMetacat.warn("No SystemMetadata found for: " + docid);
1196
		}
1197
1198
		Calendar created = Calendar.getInstance();
1199
		created.setTime(doc.getCreateDate());
1200
		Calendar updated = Calendar.getInstance();
1201
		updated.setTime(doc.getUpdateDate());
1202
1203 7379 leinfelder
		sb.append("<docname><![CDATA[").append(doc.getDocname());
1204
		sb.append("]]></docname><doctype>").append(doc.getDoctype());
1205 6708 leinfelder
		sb.append("</doctype>");
1206
		sb.append("<user_owner>").append(doc.getUserowner());
1207
		sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
1208
		sb.append("</user_updated>");
1209
		sb.append("<date_created>");
1210
		sb.append(DateTimeMarshaller.serializeDateToUTC(doc.getCreateDate()));
1211
		sb.append("</date_created>");
1212
		sb.append("<date_updated>");
1213
		sb.append(DateTimeMarshaller.serializeDateToUTC(doc.getUpdateDate()));
1214
		sb.append("</date_updated>");
1215
		sb.append("<home_server>");
1216
		sb.append(doc.getDocHomeServer());
1217
		sb.append("</home_server>");
1218
		sb.append("<public_access>").append(doc.getPublicaccess());
1219
		sb.append("</public_access><rev>").append(doc.getRev());
1220
		sb.append("</rev>");
1221
1222
		sb.append("<accessControl>");
1223
1224
		AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
1225
		sb.append(acfsf.getAccessString());
1226
1227
		sb.append("</accessControl>");
1228
1229
		sb.append("</documentinfo>");
1230
1231
		return sb.toString();
1232
	}
1233
1234
	/**
1235 6118 leinfelder
	 * Sends System Metadata as XML
1236
	 */
1237
	protected static void handleGetSystemMetadataRequest(
1238
			Hashtable<String, String[]> params, HttpServletResponse response) {
1239
		String guid = ((String[]) (params.get("guid")))[0];
1240
		String systemMetadataXML = null;
1241
		try {
1242
1243
			// serialize the System Metadata as XML
1244
			SystemMetadata systemMetadata = IdentifierManager.getInstance().getSystemMetadata(guid);
1245
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
1246 6367 leinfelder
			TypeMarshaller.marshalTypeToOutputStream(systemMetadata, baos);
1247 6118 leinfelder
			systemMetadataXML = baos.toString("UTF-8");
1248
1249
			// get a writer for sending back to response
1250
			response.setContentType("text/xml");
1251
			Writer out = response.getWriter();
1252
			out.write(systemMetadataXML);
1253
			out.close();
1254 2286 tao
1255 6118 leinfelder
		} catch (Exception e) {
1256
			String msg = "ReplicationService.handleGetSystemMetadataRequest for guid: " + guid + " : " + e.getMessage();
1257
			logMetacat.error(msg);
1258
			logReplication.error(msg);
1259
		}
1260
1261
	}
1262 6119 leinfelder
1263
	/**
1264
	 * when a forcereplication request comes in, local host sends a read request
1265
	 * to the requesting server (remote server) for the specified docid. Then
1266
	 * store it in local database.
1267
	 */
1268
	protected static void handleForceReplicateSystemMetadataRequest(
1269
			Hashtable<String, String[]> params, HttpServletResponse response,
1270
			HttpServletRequest request) {
1271
		String server = ((String[]) params.get("server"))[0]; // the server that
1272
		String guid = ((String[]) params.get("guid"))[0]; // sent the document
1273
1274
		try {
1275
			logReplication.info("ReplicationService.handleForceReplicateSystemMetadataRequest - Force replication system metadata request from: " + server);
1276
			// get the system metadata from server
1277
			URL docinfourl = new URL("https://" + server + "?server="
1278
					+ MetacatUtil.getLocalReplicationServerName()
1279
					+ "&action=getsystemmetadata&guid=" + guid);
1280
1281
			String systemMetadataXML = ReplicationService.getURLContent(docinfourl);
1282
1283
			// process system metadata
1284
			if (systemMetadataXML != null) {
1285
				SystemMetadata sysMeta =
1286 6367 leinfelder
					TypeMarshaller.unmarshalTypeFromStream(
1287 6119 leinfelder
							SystemMetadata.class,
1288
							new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
1289 6447 leinfelder
				HazelcastService.getInstance().getSystemMetadataMap().put(sysMeta.getIdentifier(), sysMeta);
1290 7812 leinfelder
				// submit for indexing
1291 8647 leinfelder
                MetacatSolrIndex.getInstance().submit(sysMeta.getIdentifier(), sysMeta, null, true);
1292 6119 leinfelder
			}
1293
1294
			logReplication.info("ReplicationService.handleForceReplicateSystemMetadataRequest - processed guid: " + guid);
1295 6542 leinfelder
			EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), REPLICATIONUSER, guid, "systemMetadata");
1296 6118 leinfelder
1297 6119 leinfelder
		} catch (Exception e) {
1298
			logMetacat.error("ReplicationService.handleForceReplicateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG, e);
1299
			logReplication.error("ReplicationService.handleForceReplicateRequest - General error when processing guid: " + guid, e);
1300
		}
1301
	}
1302
1303 5014 daigle
	/**
1304
	 * Sends a datafile to a remote host
1305
	 */
1306
	protected static void handleGetDataFileRequest(OutputStream outPut,
1307
			Hashtable<String, String[]> params, HttpServletResponse response)
1308 2286 tao
1309 5014 daigle
	{
1310
		// File path for data file
1311
		String filepath;
1312
		// Request docid
1313
		String docId = ((String[]) (params.get("docid")))[0];
1314
		//check if the doicd is null
1315
		if (docId == null) {
1316
			logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1317
			logReplication.error("ReplicationService.handleGetDataFileRequest - Didn't specify docid for replication");
1318
			return;
1319
		}
1320 2286 tao
1321 5014 daigle
		//try to open a https stream to test if the request server's public key
1322
		//in the key store, this is security issue
1323
		try {
1324
			filepath = PropertyService.getProperty("application.datafilepath");
1325
			String server = params.get("server")[0];
1326
			URL u = new URL("https://" + server + "?server="
1327
					+ MetacatUtil.getLocalReplicationServerName() + "&action=test");
1328
			String test = ReplicationService.getURLContent(u);
1329
			//couldn't pass the test
1330
			if (test.indexOf("successfully") == -1) {
1331
				//response.setContentType("text/xml");
1332
				//outPut.println("<error>Couldn't pass the trust test</error>");
1333
				logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1334
				logReplication.error("ReplicationService.handleGetDataFileRequest - Couldn't pass the trust test");
1335
				return;
1336
			}
1337
		}//try
1338
		catch (Exception ee) {
1339
			return;
1340
		}//catch
1341 2286 tao
1342 5014 daigle
		if (!filepath.endsWith("/")) {
1343
			filepath += "/";
1344
		}
1345
		// Get file aboslute file name
1346
		String filename = filepath + docId;
1347 2286 tao
1348 5014 daigle
		//MIME type
1349
		String contentType = null;
1350
		if (filename.endsWith(".xml")) {
1351
			contentType = "text/xml";
1352
		} else if (filename.endsWith(".css")) {
1353
			contentType = "text/css";
1354
		} else if (filename.endsWith(".dtd")) {
1355
			contentType = "text/plain";
1356
		} else if (filename.endsWith(".xsd")) {
1357
			contentType = "text/xml";
1358
		} else if (filename.endsWith("/")) {
1359
			contentType = "text/html";
1360
		} else {
1361
			File f = new File(filename);
1362
			if (f.isDirectory()) {
1363
				contentType = "text/html";
1364
			} else {
1365
				contentType = "application/octet-stream";
1366
			}
1367
		}
1368 2286 tao
1369 5014 daigle
		// Set the mime type
1370
		response.setContentType(contentType);
1371 2286 tao
1372 5014 daigle
		// Get the content of the file
1373
		FileInputStream fin = null;
1374
		try {
1375
			// FileInputStream to metacat
1376
			fin = new FileInputStream(filename);
1377
			// 4K buffer
1378
			byte[] buf = new byte[4 * 1024];
1379
			// Read data from file input stream to byte array
1380
			int b = fin.read(buf);
1381
			// Write to outStream from byte array
1382
			while (b != -1) {
1383
				outPut.write(buf, 0, b);
1384
				b = fin.read(buf);
1385
			}
1386
			// close file input stream
1387
			fin.close();
1388 2286 tao
1389 8304 jones
		} catch (Exception e) {
1390 5014 daigle
			logMetacat.error("ReplicationService.handleGetDataFileRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1391
			logReplication.error("ReplicationService.handleGetDataFileRequest - error getting data file from MetacatReplication."
1392
					+ "handlGetDataFileRequest " + e.getMessage());
1393
			e.printStackTrace(System.out);
1394 8304 jones
		} finally {
1395
		    IOUtils.closeQuietly(fin);
1396
		}
1397 2286 tao
1398 5014 daigle
	}
1399
1400
	/**
1401 4854 daigle
	 * Sends a document to a remote host
1402
	 */
1403 5755 leinfelder
	protected static void handleGetDocumentRequest(
1404 4854 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1405 2286 tao
1406 4854 daigle
		String urlString = null;
1407
		String documentPath = null;
1408 5755 leinfelder
		String errorMsg = null;
1409 8297 jones
		FileOutputStream fos = null;
1410 8301 jones
		InputStream is = null;
1411
		OutputStream outputStream = null;
1412 4854 daigle
		try {
1413
			// try to open a https stream to test if the request server's public
1414
			// key
1415
			// in the key store, this is security issue
1416
			String server = params.get("server")[0];
1417
			urlString = "https://" + server + "?server="
1418
					+ MetacatUtil.getLocalReplicationServerName() + "&action=test";
1419
			URL u = new URL(urlString);
1420 5014 daigle
			String test = ReplicationService.getURLContent(u);
1421 4854 daigle
			// couldn't pass the test
1422
			if (test.indexOf("successfully") == -1) {
1423
				response.setContentType("text/xml");
1424 5755 leinfelder
				Writer out = response.getWriter();
1425
				out.write("<error>Couldn't pass the trust test " + test + " </error>");
1426 4854 daigle
				out.close();
1427
				return;
1428
			}
1429 2286 tao
1430 4854 daigle
			String docid = params.get("docid")[0];
1431 5014 daigle
			logReplication.debug("ReplicationService.handleGetDocumentRequest - MetacatReplication.handleGetDocumentRequest for docid: "
1432
					+ docid);
1433 4854 daigle
			DocumentImpl di = new DocumentImpl(docid);
1434 2286 tao
1435 5014 daigle
			String documentDir = PropertyService
1436
					.getProperty("application.documentfilepath");
1437 4854 daigle
			documentPath = documentDir + FileUtil.getFS() + docid;
1438 4488 daigle
1439 4854 daigle
			// if the document does not exist on disk, read it from db and write
1440
			// it to disk.
1441
			if (FileUtil.getFileStatus(documentPath) == FileUtil.DOES_NOT_EXIST
1442
					|| FileUtil.getFileSize(documentPath) == 0) {
1443 8297 jones
				fos = new FileOutputStream(documentPath);
1444 8301 jones
				is = di.toXml(fos, null, null, true);
1445 8297 jones
				fos.close();
1446 8301 jones
				is.close();
1447 4854 daigle
			}
1448 2286 tao
1449 5752 leinfelder
			// read the file from disk and send it to outputstream
1450 8301 jones
			outputStream = response.getOutputStream();
1451
			is = di.readFromFileSystem(outputStream, null, null, documentPath);
1452
			is.close();
1453
			outputStream.close();
1454 2286 tao
1455 5014 daigle
			logReplication.info("ReplicationService.handleGetDocumentRequest - document " + docid + " sent");
1456 4854 daigle
1457 5755 leinfelder
			// return to avoid continuing to the error reporting section at the end
1458
			return;
1459
1460 4854 daigle
		} catch (MalformedURLException mue) {
1461 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1462
			logReplication.error("ReplicationService.handleGetDocumentRequest - Url error when getting document from MetacatReplication."
1463 4854 daigle
					+ "handlGetDocumentRequest for url: " + urlString + " : "
1464
					+ mue.getMessage());
1465
			// e.printStackTrace(System.out);
1466 5755 leinfelder
1467 4854 daigle
		} catch (IOException ioe) {
1468 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1469
			logReplication.error("ReplicationService.handleGetDocumentRequest - I/O error when getting document from MetacatReplication."
1470
					+ "handlGetDocumentRequest for file: " + documentPath + " : "
1471
					+ ioe.getMessage());
1472 5755 leinfelder
			errorMsg = ioe.getMessage();
1473 4854 daigle
		} catch (PropertyNotFoundException pnfe) {
1474 5014 daigle
			logMetacat.error("ReplicationService.handleGetDocumentRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1475
			logReplication
1476
					.error("ReplicationService.handleGetDocumentRequest - Error getting property when getting document from MetacatReplication."
1477
							+ "handlGetDocumentRequest for file: "
1478
							+ documentPath
1479
							+ " : "
1480
							+ pnfe.getMessage());
1481 4854 daigle
			// e.printStackTrace(System.out);
1482 5755 leinfelder
			errorMsg = pnfe.getMessage();
1483 4854 daigle
		} catch (McdbException me) {
1484 5014 daigle
			logReplication
1485
					.error("ReplicationService.handleGetDocumentRequest - Document implementation error  getting property when getting document from MetacatReplication."
1486
							+ "handlGetDocumentRequest for file: "
1487
							+ documentPath
1488
							+ " : "
1489
							+ me.getMessage());
1490 4854 daigle
			// e.printStackTrace(System.out);
1491 5755 leinfelder
			errorMsg = me.getMessage();
1492 8810 leinfelder
		} catch (Exception e) {
1493
			logReplication
1494
			.error("ReplicationService.handleGetDocumentRequest - General exception encountered."
1495
					+ "handlGetDocumentRequest for file: "
1496
					+ documentPath
1497
					+ " : "
1498
					+ e.getMessage());
1499
			// e.printStackTrace(System.out);
1500
			errorMsg = e.getMessage();
1501 8297 jones
		} finally {
1502 8299 jones
            IOUtils.closeQuietly(fos);
1503 8301 jones
            IOUtils.closeQuietly(is);
1504
            IOUtils.closeQuietly(outputStream);
1505 4854 daigle
		}
1506 5755 leinfelder
1507
		// report any errors if we got here
1508
		response.setContentType("text/xml");
1509
		Writer out = null;
1510
		try {
1511
			response.getWriter();
1512
			out = response.getWriter();
1513
			out.write("<error>" + errorMsg + "</error>");
1514
		} catch (Exception e) {
1515
			logMetacat.error(e.getMessage(), e);
1516
		} finally {
1517
			try {
1518
				out.close();
1519
			} catch (IOException e) {
1520
				logMetacat.error(e.getMessage(), e);
1521
			}
1522
		}
1523
1524 4854 daigle
1525
	}
1526
1527 5014 daigle
	/**
1528 4854 daigle
	 * Sends a list of all of the documents on this sever along with their
1529
	 * revision numbers. The format is: <!ELEMENT replication (server, updates)>
1530
	 * <!ELEMENT server (#PCDATA)> <!ELEMENT updates ((updatedDocument |
1531
	 * deleteDocument | revisionDocument)*)> <!ELEMENT updatedDocument (docid,
1532
	 * rev, datafile*)> <!ELEMENT deletedDocument (docid, rev)> <!ELEMENT
1533
	 * revisionDocument (docid, rev, datafile*)> <!ELEMENT docid (#PCDATA)>
1534
	 * <!ELEMENT rev (#PCDATA)> <!ELEMENT datafile (#PCDATA)> note that the rev
1535
	 * in deletedDocument is always empty. I just left it in there to make the
1536
	 * parser implementation easier.
1537
	 */
1538 5755 leinfelder
	protected static void handleUpdateRequest(Hashtable<String, String[]> params,
1539 5014 daigle
			HttpServletResponse response) {
1540
		// Checked out DBConnection
1541
		DBConnection dbConn = null;
1542
		// DBConenction serial number when checked it out
1543
		int serialNumber = -1;
1544
		PreparedStatement pstmt = null;
1545
		// Server list to store server info of xml_replication table
1546
		ReplicationServerList serverList = null;
1547 5755 leinfelder
1548
		// a writer for response
1549
		Writer out = null;
1550 2286 tao
1551 5014 daigle
		try {
1552 5755 leinfelder
			// get writer, TODO: encoding?
1553
			response.setContentType("text/xml");
1554
			out = response.getWriter();
1555
1556 5014 daigle
			// Check out a DBConnection from pool
1557
			dbConn = DBConnectionPool
1558
					.getDBConnection("MetacatReplication.handleUpdateRequest");
1559
			serialNumber = dbConn.getCheckOutSerialNumber();
1560
			// Create a server list from xml_replication table
1561
			serverList = new ReplicationServerList();
1562 2286 tao
1563 5014 daigle
			// Get remote server name from param
1564
			String server = ((String[]) params.get("server"))[0];
1565
			// If no servr name in param, return a error
1566
			if (server == null || server.equals("")) {
1567 5755 leinfelder
				out.write("<error>Request didn't specify server name</error>");
1568 5014 daigle
				out.close();
1569
				return;
1570
			}//if
1571 2286 tao
1572 5014 daigle
			//try to open a https stream to test if the request server's public key
1573
			//in the key store, this is security issue
1574 5440 berkley
			String testUrl = "https://" + server + "?server="
1575 5441 berkley
            + MetacatUtil.getLocalReplicationServerName() + "&action=test";
1576 5440 berkley
			logReplication.info("Running trust test: " + testUrl);
1577
			URL u = new URL(testUrl);
1578 5014 daigle
			String test = ReplicationService.getURLContent(u);
1579 5441 berkley
			logReplication.info("Ouput from test is '" + test + "'");
1580 5014 daigle
			//couldn't pass the test
1581
			if (test.indexOf("successfully") == -1) {
1582 5441 berkley
			    logReplication.error("Trust test failed.");
1583 5755 leinfelder
				out.write("<error>Couldn't pass the trust test</error>");
1584 5014 daigle
				out.close();
1585
				return;
1586
			}
1587 5441 berkley
			logReplication.info("Trust test succeeded.");
1588 2286 tao
1589 5014 daigle
			// Check if local host configure to replicate xml documents to remote
1590
			// server. If not send back a error message
1591
			if (!serverList.getReplicationValue(server)) {
1592 5755 leinfelder
				out.write("<error>Configuration not allow to replicate document to you</error>");
1593 5014 daigle
				out.close();
1594
				return;
1595
			}//if
1596 2286 tao
1597 5014 daigle
			// Store the sql command
1598
			StringBuffer docsql = new StringBuffer();
1599
			StringBuffer revisionSql = new StringBuffer();
1600 7356 leinfelder
1601 5014 daigle
			// Store the data set file
1602
			Vector<Vector<String>> packageFiles = new Vector<Vector<String>>();
1603 2286 tao
1604 5014 daigle
			// Append local server's name and replication servlet to doclist
1605 7356 leinfelder
			out.append("<?xml version=\"1.0\"?><replication>");
1606
			out.append("<server>")
1607 5014 daigle
					.append(MetacatUtil.getLocalReplicationServerName());
1608
			//doclist.append(util.getProperty("replicationpath"));
1609 7356 leinfelder
			out.append("</server><updates>");
1610 2286 tao
1611 5014 daigle
			// Get correct docid that reside on this server according the requesting
1612
			// server's replicate and data replicate value in xml_replication table
1613 5319 jones
			docsql.append(DatabaseService.getInstance().getDBAdapter().getReplicationDocumentListSQL());
1614 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)) ");
1615
			revisionSql.append("select docid, rev, doctype from xml_revisions ");
1616
			// If the localhost is not a hub to the remote server, only replicate
1617
			// the docid' which home server is local host (server_location =1)
1618
			if (!serverList.getHubValue(server)) {
1619
				String serverLocationDoc = " and a.server_location = 1";
1620
				String serverLocationRev = "where server_location = 1";
1621
				docsql.append(serverLocationDoc);
1622
				revisionSql.append(serverLocationRev);
1623
			}
1624
			logReplication.info("ReplicationService.handleUpdateRequest - Doc sql: " + docsql.toString());
1625 2286 tao
1626 5014 daigle
			// Get any deleted documents
1627 7636 jones
			StringBuffer delsql = new StringBuffer();
1628 7638 leinfelder
			delsql.append("SELECT t1.docid FROM xml_revisions t1 LEFT JOIN xml_documents t2 on t1.docid = t2.docid WHERE t2.docid IS NULL ");
1629 7636 jones
1630 5014 daigle
			// If the localhost is not a hub to the remote server, only replicate
1631
			// the docid' which home server is local host (server_location =1)
1632
			if (!serverList.getHubValue(server)) {
1633 7636 jones
				delsql.append("and t1.server_location = 1");
1634 5014 daigle
			}
1635
			logReplication.info("ReplicationService.handleUpdateRequest - Deleted sql: " + delsql.toString());
1636 2286 tao
1637 5014 daigle
			// Get docid list of local host
1638
			pstmt = dbConn.prepareStatement(docsql.toString());
1639
			pstmt.execute();
1640
			ResultSet rs = pstmt.getResultSet();
1641
			boolean tablehasrows = rs.next();
1642
			//If metacat configed to replicate data file
1643
			//if ((util.getProperty("replicationsenddata")).equals("on"))
1644
			boolean replicateData = serverList.getDataReplicationValue(server);
1645
			if (replicateData) {
1646
				while (tablehasrows) {
1647
					String recordDoctype = rs.getString(3);
1648
					Vector<String> packagedoctypes = MetacatUtil
1649
							.getOptionList(PropertyService
1650
									.getProperty("xml.packagedoctype"));
1651
					//if this is a package file, put it at the end
1652
					//because if a package file is read before all of the files it
1653
					//refers to are loaded then there is an error
1654
					if (recordDoctype != null && !packagedoctypes.contains(recordDoctype)) {
1655
						//If this is not data file
1656
						if (!recordDoctype.equals("BIN")) {
1657
							//for non-data file document
1658 7356 leinfelder
							out.append("<updatedDocument>");
1659
							out.append("<docid>").append(rs.getString(1));
1660
							out.append("</docid><rev>" + rs.getInt(2));
1661
							out.append("</rev>");
1662
							out.append("</updatedDocument>");
1663 5014 daigle
						}//if
1664
						else {
1665
							//for data file document, in datafile attributes
1666
							//we put "datafile" value there
1667 7356 leinfelder
							out.append("<updatedDocument>");
1668
							out.append("<docid>").append(rs.getString(1));
1669
							out.append("</docid><rev>" + rs.getInt(2));
1670
							out.append("</rev>");
1671
							out.append("<datafile>");
1672
							out.append(DATA_FILE_FLAG);
1673
							out.append("</datafile>");
1674
							out.append("</updatedDocument>");
1675 5014 daigle
						}//else
1676
					}//if packagedoctpes
1677
					else { //the package files are saved to be put into the xml later.
1678
						Vector<String> v = new Vector<String>();
1679
						v.add(rs.getString(1));
1680
						v.add(String.valueOf(rs.getInt(2)));
1681
						packageFiles.add(v);
1682
					}//esle
1683
					tablehasrows = rs.next();
1684
				}//while
1685
			}//if
1686
			else //metacat was configured not to send data file
1687
			{
1688
				while (tablehasrows) {
1689
					String recordDoctype = rs.getString(3);
1690
					if (!recordDoctype.equals("BIN")) { //don't replicate data files
1691
						Vector<String> packagedoctypes = MetacatUtil
1692
								.getOptionList(PropertyService
1693
										.getProperty("xml.packagedoctype"));
1694
						if (recordDoctype != null
1695
								&& !packagedoctypes.contains(recordDoctype)) { //if this is a package file, put it at the end
1696
							//because if a package file is read before all of the files it
1697
							//refers to are loaded then there is an error
1698 7356 leinfelder
							out.append("<updatedDocument>");
1699
							out.append("<docid>" + rs.getString(1));
1700
							out.append("</docid><rev>" + rs.getInt(2));
1701
							out.append("</rev>");
1702
							out.append("</updatedDocument>");
1703 5014 daigle
						} else { //the package files are saved to be put into the xml later.
1704
							Vector<String> v = new Vector<String>();
1705
							v.add(rs.getString(1));
1706
							v.add(String.valueOf(rs.getInt(2)));
1707
							packageFiles.add(v);
1708
						}
1709
					}//if
1710
					tablehasrows = rs.next();
1711
				}//while
1712
			}//else
1713 2286 tao
1714 5014 daigle
			pstmt = dbConn.prepareStatement(delsql.toString());
1715
			//usage count should increas 1
1716
			dbConn.increaseUsageCount(1);
1717 2286 tao
1718 5014 daigle
			pstmt.execute();
1719
			rs = pstmt.getResultSet();
1720
			tablehasrows = rs.next();
1721
			while (tablehasrows) { //handle the deleted documents
1722 7356 leinfelder
				out.append("<deletedDocument><docid>").append(rs.getString(1));
1723
				out.append("</docid><rev></rev></deletedDocument>");
1724 5014 daigle
				//note that rev is always empty for deleted docs
1725
				tablehasrows = rs.next();
1726
			}
1727 2286 tao
1728 5014 daigle
			//now we can put the package files into the xml results
1729
			for (int i = 0; i < packageFiles.size(); i++) {
1730
				Vector<String> v = packageFiles.elementAt(i);
1731 7356 leinfelder
				out.append("<updatedDocument>");
1732
				out.append("<docid>").append(v.elementAt(0));
1733
				out.append("</docid><rev>");
1734
				out.append(v.elementAt(1));
1735
				out.append("</rev>");
1736
				out.append("</updatedDocument>");
1737 5014 daigle
			}
1738
			// add revision doc list
1739 7356 leinfelder
			out.append(prepareRevisionDoc(dbConn, revisionSql.toString(),
1740 5014 daigle
					replicateData));
1741 2286 tao
1742 7356 leinfelder
			out.append("</updates></replication>");
1743
			logReplication.info("ReplicationService.handleUpdateRequest - done writing to output stream.");
1744 5014 daigle
			pstmt.close();
1745
			//conn.close();
1746 2286 tao
1747 5014 daigle
		} catch (Exception e) {
1748
			logMetacat.error("ReplicationService.handleUpdateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1749
			logReplication.error("ReplicationService.handleUpdateRequest - error in MetacatReplication." + "handleupdaterequest: "
1750
					+ e.getMessage());
1751
			//e.printStackTrace(System.out);
1752 5755 leinfelder
			try {
1753
				out.write("<error>" + e.getMessage() + "</error>");
1754
			} catch (IOException e1) {
1755
				logMetacat.error(e1.getMessage(), e1);
1756
			}
1757 5014 daigle
		} finally {
1758
			try {
1759
				pstmt.close();
1760
			}//try
1761
			catch (SQLException ee) {
1762
				logMetacat.error("ReplicationService.handleUpdateRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1763
				logReplication.error("ReplicationService.handleUpdateRequest - Error in MetacatReplication."
1764
						+ "handleUpdaterequest to close pstmt: " + ee.getMessage());
1765
			}//catch
1766
			finally {
1767
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1768
			}//finally
1769 5755 leinfelder
			try {
1770
				out.close();
1771
			} catch (IOException e) {
1772
				logMetacat.error(e.getMessage(), e);
1773
			}
1774 5014 daigle
		}//finally
1775 2286 tao
1776 5014 daigle
	}//handlUpdateRequest
1777 2286 tao
1778 6015 leinfelder
	/**
1779
	 *
1780
	 * @param dbConn connection for doing the update
1781
	 * @param docid the document id to update
1782
	 * @param owner the user_owner
1783
	 * @param updater the user_updated
1784
	 * @throws SQLException
1785
	 */
1786
	public static void updateUserOwner(DBConnection dbConn, String docid, String owner, String updater) throws SQLException {
1787
1788
		String sql =
1789
			"UPDATE xml_documents " +
1790
			"SET user_owner = ?, " +
1791
			"user_updated = ? " +
1792
			"WHERE docid = ?;";
1793
		PreparedStatement pstmt = dbConn.prepareStatement(sql);
1794
		//usage count should increas 1
1795
		dbConn.increaseUsageCount(1);
1796
1797
		docid = DocumentUtil.getSmartDocId(docid);
1798
		pstmt.setString(1, owner);
1799
		pstmt.setString(2, updater);
1800
		pstmt.setString(3, docid);
1801
		pstmt.execute();
1802
		pstmt.close();
1803
1804
		dbConn.commit();
1805
	}
1806
1807 5014 daigle
	/*
1808
	 * This method will get the xml string for document in xml_revision
1809
	 * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1810
	 */
1811
	private static String prepareRevisionDoc(DBConnection dbConn, String revSql,
1812
			boolean replicateData) throws Exception {
1813
		logReplication.warn("ReplicationService.prepareRevisionDoc - The revision document sql is " + revSql);
1814
		StringBuffer revDocList = new StringBuffer();
1815
		PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1816
		//usage count should increas 1
1817
		dbConn.increaseUsageCount(1);
1818 2286 tao
1819 5014 daigle
		pstmt.execute();
1820
		ResultSet rs = pstmt.getResultSet();
1821 7337 leinfelder
		logReplication.warn("Processing replication revision for documents");
1822 7338 leinfelder
		while (rs.next()) {
1823 5014 daigle
			String recordDoctype = rs.getString(3);
1824 2286 tao
1825 5014 daigle
			//If this is data file and it isn't configured to replicate data
1826
			if (recordDoctype.equals("BIN") && !replicateData) {
1827 7338 leinfelder
				logMetacat.debug("SKipping data file because data replication is not configured");
1828
1829 5014 daigle
				// do nothing
1830
			} else {
1831 7337 leinfelder
				String docid = rs.getString(1);
1832
				int rev = rs.getInt(2);
1833
				logMetacat.debug("Processing replication revision for docid: " + docid + "." + rev);
1834 2597 tao
1835 5014 daigle
				revDocList.append("<revisionDocument>");
1836 7337 leinfelder
				revDocList.append("<docid>").append(docid);
1837
				revDocList.append("</docid><rev>").append(rev);
1838 5014 daigle
				revDocList.append("</rev>");
1839
				// data file
1840
				if (recordDoctype.equals("BIN")) {
1841
					revDocList.append("<datafile>");
1842 7337 leinfelder
					revDocList.append(DATA_FILE_FLAG);
1843 5014 daigle
					revDocList.append("</datafile>");
1844
				}
1845
				revDocList.append("</revisionDocument>");
1846 2286 tao
1847 5014 daigle
			}//else
1848
		}
1849
		//System.out.println("The revision list is"+ revDocList.toString());
1850
		return revDocList.toString();
1851
	}
1852 2286 tao
1853 5014 daigle
	/**
1854
	 * Returns the xml_catalog table encoded in xml
1855
	 */
1856
	public static String getCatalogXML() {
1857 5755 leinfelder
		return handleGetCatalogRequest(null, null, false);
1858 5014 daigle
	}
1859 2286 tao
1860 5014 daigle
	/**
1861
	 * Sends the contents of the xml_catalog table encoded in xml
1862
	 * The xml format is:
1863
	 * <!ELEMENT xml_catalog (row*)>
1864
	 * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1865
	 *                system_id)>
1866
	 * All of the sub elements of row are #PCDATA
1867 2286 tao
1868 5014 daigle
	 * If printFlag == false then do not print to out.
1869
	 */
1870 5755 leinfelder
	protected static String handleGetCatalogRequest(
1871 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response,
1872
			boolean printFlag) {
1873
		DBConnection dbConn = null;
1874
		int serialNumber = -1;
1875
		PreparedStatement pstmt = null;
1876 5755 leinfelder
		Writer out = null;
1877 5014 daigle
		try {
1878 5755 leinfelder
			// get writer, TODO: encoding?
1879 5944 berkley
		    if(printFlag)
1880
		    {
1881
		        response.setContentType("text/xml");
1882
		        out = response.getWriter();
1883
		    }
1884 5014 daigle
			/*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1885
			                                          "handleGetCatalogRequest");*/
1886
			dbConn = DBConnectionPool
1887
					.getDBConnection("MetacatReplication.handleGetCatalogRequest");
1888
			serialNumber = dbConn.getCheckOutSerialNumber();
1889
			pstmt = dbConn.prepareStatement("select entry_type, "
1890
					+ "source_doctype, target_doctype, public_id, "
1891
					+ "system_id from xml_catalog");
1892
			pstmt.execute();
1893
			ResultSet rs = pstmt.getResultSet();
1894
			boolean tablehasrows = rs.next();
1895
			StringBuffer sb = new StringBuffer();
1896
			sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1897
			while (tablehasrows) {
1898
				sb.append("<row><entry_type>").append(rs.getString(1));
1899
				sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1900
				sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1901
				sb.append("</target_doctype><public_id>").append(rs.getString(4));
1902
				// system id may not have server url on front.  Add it if not.
1903
				String systemID = rs.getString(5);
1904
				if (!systemID.startsWith("http://")) {
1905
					systemID = SystemUtil.getContextURL() + systemID;
1906
				}
1907
				sb.append("</public_id><system_id>").append(systemID);
1908
				sb.append("</system_id></row>");
1909 2286 tao
1910 5014 daigle
				tablehasrows = rs.next();
1911
			}
1912
			sb.append("</xml_catalog>");
1913
			//conn.close();
1914
			if (printFlag) {
1915
				response.setContentType("text/xml");
1916 5755 leinfelder
				out.write(sb.toString());
1917 5014 daigle
			}
1918
			pstmt.close();
1919
			return sb.toString();
1920
		} catch (Exception e) {
1921
			logMetacat.error("ReplicationService.handleGetCatalogRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1922
			logReplication.error("ReplicationService.handleGetCatalogRequest - error in MetacatReplication.handleGetCatalogRequest:"
1923
					+ e.getMessage());
1924
			e.printStackTrace(System.out);
1925
			if (printFlag) {
1926 5755 leinfelder
				try {
1927
					out.write("<error>" + e.getMessage() + "</error>");
1928
				} catch (IOException e1) {
1929
					logMetacat.error(e1.getMessage(), e1);
1930
				}
1931 5014 daigle
			}
1932
		} finally {
1933
			try {
1934
				pstmt.close();
1935
			}//try
1936
			catch (SQLException ee) {
1937
				logMetacat.error("ReplicationService.handleGetCatalogRequest - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1938
				logReplication.error("ReplicationService.handleGetCatalogRequest - Error in MetacatReplication.handleGetCatalogRequest: "
1939
						+ ee.getMessage());
1940
			}//catch
1941
			finally {
1942
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1943
			}//finally
1944 5755 leinfelder
			if (out != null) {
1945
				try {
1946
					out.close();
1947
				} catch (IOException e1) {
1948
					logMetacat.error(e1.getMessage(), e1);
1949
				}
1950
			}
1951 5014 daigle
		}//finally
1952 2286 tao
1953 5014 daigle
		return null;
1954
	}
1955 2286 tao
1956 5014 daigle
	/**
1957
	 * Sends the current system date to the remote server.  Using this action
1958
	 * for replication gets rid of any problems with syncronizing clocks
1959
	 * because a time specific to a document is always kept on its home server.
1960
	 */
1961 5755 leinfelder
	protected static void handleGetTimeRequest(
1962 5014 daigle
			Hashtable<String, String[]> params, HttpServletResponse response) {
1963 5755 leinfelder
1964 6614 leinfelder
		// use standard format -- the receiving end wants this too
1965
		String dateString = DateTimeMarshaller.serializeDateToUTC(Calendar.getInstance().getTime());
1966 6595 leinfelder
1967 5755 leinfelder
		// get a writer for sending back to response
1968 5014 daigle
		response.setContentType("text/xml");
1969 5755 leinfelder
		Writer out = null;
1970
		try {
1971
			out = response.getWriter();
1972
			out.write("<timestamp>" + dateString + "</timestamp>");
1973
			out.close();
1974
		} catch (IOException e) {
1975
			logMetacat.error(e.getMessage(), e);
1976
		}
1977
1978 5014 daigle
	}
1979 2286 tao
1980 5014 daigle
	/**
1981
	 * this method handles the timeout for a file lock.  when a lock is
1982
	 * granted it is granted for 30 seconds.  When this thread runs out
1983
	 * it deletes the docid from the queue, thus eliminating the lock.
1984
	 */
1985
	public void run() {
1986
		try {
1987
			logReplication.info("ReplicationService.run - thread started for docid: "
1988
					+ (String) fileLocks.elementAt(0));
1989 2286 tao
1990 5014 daigle
			Thread.sleep(30000); //the lock will expire in 30 seconds
1991
			logReplication.info("thread for docid: "
1992
					+ (String) fileLocks.elementAt(fileLocks.size() - 1) + " exiting.");
1993 2286 tao
1994 5014 daigle
			fileLocks.remove(fileLocks.size() - 1);
1995
			//fileLocks is treated as a FIFO queue.  If there are more than one lock
1996
			//in the vector, the first one inserted will be removed.
1997
		} catch (Exception e) {
1998
			logMetacat.error("ReplicationService.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1999
			logReplication.error("ReplicationService.run - error in file lock thread from "
2000
					+ "MetacatReplication.run: " + e.getMessage());
2001
		}
2002
	}
2003 2286 tao
2004 5014 daigle
	/**
2005
	 * Returns the name of a server given a serverCode
2006
	 * @param serverCode the serverid of the server
2007
	 * @return the servername or null if the specified serverCode does not
2008
	 *         exist.
2009
	 */
2010
	public static String getServerNameForServerCode(int serverCode) {
2011
		//System.out.println("serverid: " + serverCode);
2012
		DBConnection dbConn = null;
2013
		int serialNumber = -1;
2014
		PreparedStatement pstmt = null;
2015
		try {
2016
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.getServer");
2017
			serialNumber = dbConn.getCheckOutSerialNumber();
2018
			String sql = new String("select server from "
2019 6595 leinfelder
					+ "xml_replication where serverid = ?");
2020 5014 daigle
			pstmt = dbConn.prepareStatement(sql);
2021 6595 leinfelder
			pstmt.setInt(1, serverCode);
2022 5014 daigle
			//System.out.println("getserver sql: " + sql);
2023
			pstmt.execute();
2024
			ResultSet rs = pstmt.getResultSet();
2025
			boolean tablehasrows = rs.next();
2026
			if (tablehasrows) {
2027
				//System.out.println("server: " + rs.getString(1));
2028
				return rs.getString(1);
2029
			}
2030 2286 tao
2031 5014 daigle
			//conn.close();
2032
		} catch (Exception e) {
2033
			logMetacat.error("ReplicationService.getServerNameForServerCode - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2034
			logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacatReplication.getServer: " + e.getMessage());
2035
		} finally {
2036
			try {
2037
				pstmt.close();
2038
			}//try
2039
			catch (SQLException ee) {
2040
				logMetacat.error("ReplicationService.getServerNameForServerCode - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2041
				logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacactReplication.getserver: "
2042
						+ ee.getMessage());
2043
			}//catch
2044
			finally {
2045
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2046
			}//fianlly
2047
		}//finally
2048 2286 tao
2049 5014 daigle
		return null;
2050
		//return null if the server does not exist
2051
	}
2052 2286 tao
2053 5014 daigle
	/**
2054
	 * Returns a server code given a server name
2055
	 * @param server the name of the server
2056
	 * @return integer > 0 representing the code of the server, 0 if the server
2057
	 *  does not exist.
2058
	 */
2059
	public static int getServerCodeForServerName(String server) throws ServiceException {
2060
		DBConnection dbConn = null;
2061
		int serialNumber = -1;
2062
		PreparedStatement pstmt = null;
2063
		int serverCode = 0;
2064 2286 tao
2065 5014 daigle
		try {
2066 837 bojilova
2067 5014 daigle
			//conn = util.openDBConnection();
2068
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.getServerCode");
2069
			serialNumber = dbConn.getCheckOutSerialNumber();
2070
			pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication "
2071 6595 leinfelder
					+ "WHERE server LIKE ?");
2072
			pstmt.setString(1, server);
2073 5014 daigle
			pstmt.execute();
2074
			ResultSet rs = pstmt.getResultSet();
2075
			boolean tablehasrows = rs.next();
2076
			if (tablehasrows) {
2077
				serverCode = rs.getInt(1);
2078
				pstmt.close();
2079
				//conn.close();
2080
				return serverCode;
2081
			}
2082 837 bojilova
2083 5014 daigle
		} catch (SQLException sqle) {
2084
			throw new ServiceException("ReplicationService.getServerCodeForServerName - "
2085
					+ "SQL error when getting server code: " + sqle.getMessage());
2086 2286 tao
2087 5014 daigle
		} finally {
2088
			try {
2089
				pstmt.close();
2090
				//conn.close();
2091
			}//try
2092
			catch (Exception ee) {
2093
				logMetacat.error("ReplicationService.getServerCodeForServerName - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2094
				logReplication.error("ReplicationService.getServerNameForServerCode - Error in MetacatReplicatio.getServerCode: "
2095
						+ ee.getMessage());
2096 837 bojilova
2097 5014 daigle
			}//catch
2098
			finally {
2099
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2100
			}//finally
2101
		}//finally
2102 2286 tao
2103 5014 daigle
		return serverCode;
2104
	}
2105 8689 leinfelder
2106
	/**
2107
	 * Returns a Map of serverCode=serverName
2108
	 * @return Map of server codes to names (URIs)
2109
	 */
2110
	public static Map<Integer, String> getServerCodes() throws ServiceException {
2111
		DBConnection dbConn = null;
2112
		int serialNumber = -1;
2113
		PreparedStatement pstmt = null;
2114
2115
		Map<Integer, String> codes = new HashMap<Integer, String>();
2116 2286 tao
2117 8689 leinfelder
		try {
2118
2119
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.getServerCodes");
2120
			serialNumber = dbConn.getCheckOutSerialNumber();
2121
			pstmt = dbConn.prepareStatement("SELECT serverid, server FROM xml_replication ");
2122
			pstmt.execute();
2123
			ResultSet rs = pstmt.getResultSet();
2124
			while (rs.next()) {
2125
				int serverCode = rs.getInt(1);
2126
				String server = rs.getString(2);
2127
				codes.put(serverCode, server);
2128
			}
2129
			pstmt.close();
2130
2131
		} catch (SQLException sqle) {
2132
			throw new ServiceException("ReplicationService.getServerCodes - "
2133
					+ "SQL error when getting server map: " + sqle.getMessage());
2134
2135
		} finally {
2136
			try {
2137
				pstmt.close();
2138
			}//try
2139
			catch (Exception ee) {
2140
				logMetacat.error("ReplicationService.getServerCodes - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2141
				logReplication.error("ReplicationService.getServerCodes - Error in MetacatReplicatio.getServerCodes: "
2142
						+ ee.getMessage());
2143
2144
			}//catch
2145
			finally {
2146
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2147
			}//finally
2148
		}//finally
2149
2150
		return codes;
2151
	}
2152
2153 5014 daigle
	/**
2154
	 * Method to get a host server information for given docid
2155
	 * @param conn a connection to the database
2156
	 */
2157
	public static Hashtable<String, String> getHomeServerInfoForDocId(String docId) {
2158
		Hashtable<String, String> sl = new Hashtable<String, String>();
2159
		DBConnection dbConn = null;
2160
		int serialNumber = -1;
2161 5027 daigle
		docId = DocumentUtil.getDocIdFromString(docId);
2162 5014 daigle
		PreparedStatement pstmt = null;
2163
		int serverLocation;
2164
		try {
2165
			//get conection
2166
			dbConn = DBConnectionPool.getDBConnection("ReplicationHandler.getHomeServer");
2167
			serialNumber = dbConn.getCheckOutSerialNumber();
2168
			//get a server location from xml_document table
2169
			pstmt = dbConn.prepareStatement("select server_location from xml_documents "
2170
					+ "where docid = ?");
2171
			pstmt.setString(1, docId);
2172
			pstmt.execute();
2173
			ResultSet serverName = pstmt.getResultSet();
2174
			//get a server location
2175
			if (serverName.next()) {
2176
				serverLocation = serverName.getInt(1);
2177
				pstmt.close();
2178
			} else {
2179
				pstmt.close();
2180
				//ut.returnConnection(conn);
2181
				return null;
2182
			}
2183
			pstmt = dbConn.prepareStatement("select server, last_checked, replicate "
2184
					+ "from xml_replication where serverid = ?");
2185
			//increase usage count
2186
			dbConn.increaseUsageCount(1);
2187
			pstmt.setInt(1, serverLocation);
2188
			pstmt.execute();
2189
			ResultSet rs = pstmt.getResultSet();
2190
			boolean tableHasRows = rs.next();
2191
			if (tableHasRows) {
2192 2286 tao
2193 5014 daigle
				String server = rs.getString(1);
2194
				String last_checked = rs.getString(2);
2195
				if (!server.equals("localhost")) {
2196
					sl.put(server, last_checked);
2197
				}
2198 2286 tao
2199 5014 daigle
			} else {
2200
				pstmt.close();
2201
				//ut.returnConnection(conn);
2202
				return null;
2203
			}
2204
			pstmt.close();
2205
		} catch (Exception e) {
2206
			logMetacat.error("ReplicationService.getHomeServerInfoForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2207
			logReplication.error("ReplicationService.getHomeServerInfoForDocId - error in replicationHandler.getHomeServer(): "
2208
					+ e.getMessage());
2209
		} finally {
2210
			try {
2211
				pstmt.close();
2212
				//ut.returnConnection(conn);
2213
			} catch (Exception ee) {
2214
				logMetacat.error("ReplicationService.getHomeServerInfoForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2215
				logReplication.error("ReplicationService.getHomeServerInfoForDocId - Eror irn rplicationHandler.getHomeServer() "
2216
						+ "to close pstmt: " + ee.getMessage());
2217
			} finally {
2218
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2219
			}
2220 2286 tao
2221 5014 daigle
		}//finally
2222
		return sl;
2223
	}
2224 2286 tao
2225 5014 daigle
	/**
2226
	 * Returns a home server location  given a accnum
2227
	 * @param accNum , given accNum for a document
2228
	 *
2229
	 */
2230
	public static int getHomeServerCodeForDocId(String accNum) throws ServiceException {
2231
		DBConnection dbConn = null;
2232
		int serialNumber = -1;
2233
		PreparedStatement pstmt = null;
2234
		int serverCode = 1;
2235 5027 daigle
		String docId = DocumentUtil.getDocIdFromString(accNum);
2236 2286 tao
2237 5014 daigle
		try {
2238 1292 tao
2239 5014 daigle
			// Get DBConnection
2240
			dbConn = DBConnectionPool
2241
					.getDBConnection("ReplicationHandler.getServerLocation");
2242
			serialNumber = dbConn.getCheckOutSerialNumber();
2243
			pstmt = dbConn.prepareStatement("SELECT server_location FROM xml_documents "
2244 6595 leinfelder
					+ "WHERE docid LIKE ? ");
2245
			pstmt.setString(1, docId);
2246 5014 daigle
			pstmt.execute();
2247
			ResultSet rs = pstmt.getResultSet();
2248
			boolean tablehasrows = rs.next();
2249
			//If a document is find, return the server location for it
2250
			if (tablehasrows) {
2251
				serverCode = rs.getInt(1);
2252
				pstmt.close();
2253
				//conn.close();
2254
				return serverCode;
2255
			}
2256
			//if couldn't find in xml_documents table, we think server code is 1
2257
			//(this is new document)
2258
			else {
2259
				pstmt.close();
2260
				//conn.close();
2261
				return serverCode;
2262
			}
2263 1292 tao
2264 5014 daigle
		} catch (SQLException sqle) {
2265
			throw new ServiceException("ReplicationService.getHomeServerCodeForDocId - "
2266
					+ "SQL error when getting home server code for docid: " + docId + " : "
2267
					+ sqle.getMessage());
2268 2286 tao
2269 5014 daigle
		} finally {
2270
			try {
2271
				pstmt.close();
2272
				//conn.close();
2273 2286 tao
2274 5014 daigle
			} catch (SQLException sqle) {
2275
				logMetacat.error("ReplicationService.getHomeServerCodeForDocId - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2276
				logReplication.error("ReplicationService.getHomeServerCodeForDocId - ReplicationService.getHomeServerCodeForDocId - "
2277
						+ "SQL error when getting home server code for docid: " + docId + " : "
2278
						+ sqle.getMessage());
2279
			} finally {
2280
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2281
			}//finally
2282
		}//finally
2283
		//return serverCode;
2284
	}
2285 1292 tao
2286 5014 daigle
	/**
2287
	 * This method returns the content of a url
2288
	 * @param u the url to return the content from
2289
	 * @return a string representing the content of the url
2290
	 * @throws java.io.IOException
2291
	 */
2292 8810 leinfelder
	public static String getURLContent(URL u) throws Exception {
2293 5014 daigle
		char istreamChar;
2294
		int istreamInt;
2295 6582 leinfelder
		// get the response content
2296 9156 rnahf
		InputStream input = null;
2297
		String content = null;
2298
		try {
2299
		    input = getURLStream(u);
2300
		    logReplication.info("ReplicationService.getURLContent - After getting response from: " + u.toString());
2301
		    content = IOUtils.toString(input, "UTF-8");
2302
		}
2303
		finally {
2304
		    IOUtils.closeQuietly(input);
2305
		}
2306 8959 tao
        return content;
2307 5014 daigle
	}
2308 6582 leinfelder
2309
	/**
2310 6611 leinfelder
	 * This method returns the InputStream after opening a url
2311
	 * @param u the url to return the content from
2312
	 * @return a InputStream representing the content of the url
2313
	 * @throws java.io.IOException
2314
	 */
2315 8810 leinfelder
	public static InputStream getURLStream(URL u) throws Exception {
2316 6611 leinfelder
	    logReplication.info("Getting url stream from " + u.toString());
2317 9152 rnahf
	    logReplication.info("ReplicationService.getURLStream - Before sending request to: " + u.toString());
2318
	    // use httpclient to set up SSL
2319
2320
	    InputStream input = null;
2321
	    try {
2322
	        RestClient client = getSSLClient();
2323
	        HttpResponse response = client.doGetRequest(u.toString(),null);
2324
	        // get the response content
2325
	        StatusLine statusLine = response.getStatusLine();
2326
	        HttpEntity entity = response.getEntity();
2327
	        logReplication.info("ReplicationService.getURLStream - After getting response from: " + u.toString());
2328
	        if (statusLine.getStatusCode() >= 300) {
2329
	            throw new HttpResponseException(
2330
	                    statusLine.getStatusCode(),
2331
	                    "ReplicationService.getURLStream - " + statusLine.getReasonPhrase());
2332
	        }
2333
	        if (entity == null) {
2334
	            throw new ClientProtocolException("ReplicationService.getURLStream - Response contains no content");
2335
	        }
2336 9594 tao
	        input = new AutoCloseHttpClientInputStream(entity.getContent(), client.getHttpClient());
2337 9152 rnahf
	    }
2338
	    catch (Throwable t) {
2339
	        logReplication.error("Unexpected Throwable encountered.  Logging and moving on: " +
2340
	                t.getClass().getCanonicalName() + ": " + t.getMessage());
2341
	        logReplication.error(ExceptionUtils.getStackTrace(t));
2342
	        throw new Exception(t);
2343
	    }
2344 9149 rnahf
		return input;
2345 6611 leinfelder
	}
2346
2347
	/**
2348 8959 tao
     * This method returns a byte array after opening a url
2349
     * @param u the url to return the content from
2350
     * @return a InputStream representing the content of the url
2351
     * @throws java.io.IOException
2352
     */
2353
    public static byte[] getURLBytes(URL u) throws Exception {
2354 9156 rnahf
        InputStream input = null;
2355
        try {
2356
            input = getURLStream(u);
2357
            byte[] bytes = IOUtils.toByteArray(input);
2358
            return bytes;
2359
        }
2360
        finally {
2361
            IOUtils.closeQuietly(input);
2362
        }
2363 8959 tao
    }
2364
2365
	/**
2366 6582 leinfelder
	 * Sets up an HttpClient with SSL connection.
2367
	 * Sends client certificate to the server when doing the request.
2368
	 * @return
2369
	 */
2370 9149 rnahf
	private static RestClient getSSLClient() {
2371 9206 tao
	    RestClient sslClient = null;
2372 9149 rnahf
	    if (sslClient == null) {
2373 9096 leinfelder
2374 9149 rnahf
	        // set up this server's client identity
2375
	        String subject = null;
2376
	        try {
2377
	            // TODO: should there be alternative ways to get the key and certificate?
2378
	            String certificateFile = PropertyService.getProperty("replication.certificate.file");
2379
	            String keyFile = PropertyService.getProperty("replication.privatekey.file");
2380
	            String keyPassword = PropertyService.getProperty("replication.privatekey.password");
2381
	            X509Certificate certificate = CertificateManager.getInstance().loadCertificateFromFile(certificateFile);
2382
	            PrivateKey privateKey = CertificateManager.getInstance().loadPrivateKeyFromFile(keyFile, keyPassword);
2383
	            subject = CertificateManager.getInstance().getSubjectDN(certificate);
2384
	            CertificateManager.getInstance().registerCertificate(subject, certificate, privateKey);
2385
	        } catch (Exception e) {
2386
	            // this is pretty much required for replication communication
2387
	            logReplication.warn("Could not find server's client certificate/private key: " + e.getMessage());
2388
	        }
2389 7313 leinfelder
2390 9149 rnahf
	        try {
2391
	            RequestConfig rc = RequestConfig.custom()
2392
	                    .setConnectionRequestTimeout(CLIENTTIMEOUT)
2393
	                    .setConnectTimeout(CLIENTTIMEOUT)
2394
	                    .setSocketTimeout(CLIENTTIMEOUT).build();
2395 9596 tao
	            Boolean monitorStaleConnections = false;
2396
	            HttpClient hc = HttpUtils.getHttpClientBuilder(HttpUtils.selectSession(subject), monitorStaleConnections)
2397 9149 rnahf
	                    .setDefaultRequestConfig(rc)
2398
	                    .build();
2399
2400 9150 rnahf
	            sslClient = new RestClient(hc);
2401 9149 rnahf
	        }
2402
	        catch (FileNotFoundException e) {
2403
	            // these are somewhat expected for anonymous client use
2404
	            logReplication.warn("Could not set up SSL connection for client - likely because the certificate could not be located: " + e.getMessage());
2405
	        }
2406
	        catch (Exception e) {
2407
	            // this is likely more severe
2408
	            logReplication.error("Failed to set up SSL connection for client. Continuing. " + e.getClass() + ":: " + e.getMessage(), e);
2409
	        }
2410
	    }
2411
		return sslClient;
2412
	}
2413 9096 leinfelder
2414 6582 leinfelder
2415 2286 tao
2416 5014 daigle
//	/**
2417
//	 * Method for writing replication messages to a log file specified in
2418
//	 * metacat.properties
2419
//	 */
2420
//	public static void replLog(String message) {
2421
//		try {
2422
//			FileOutputStream fos = new FileOutputStream(PropertyService
2423
//					.getProperty("replication.logdir")
2424
//					+ "/metacatreplication.log", true);
2425
//			PrintWriter pw = new PrintWriter(fos);
2426
//			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
2427
//			java.util.Date localtime = new java.util.Date();
2428
//			String dateString = formatter.format(localtime);
2429
//			dateString += " :: " + message;
2430
//			// time stamp each entry
2431
//			pw.println(dateString);
2432
//			pw.flush();
2433
//		} catch (Exception e) {
2434
//			logReplication.error("error writing to replication log from "
2435
//					+ "MetacatReplication.replLog: " + e.getMessage());
2436
//			// e.printStackTrace(System.out);
2437
//		}
2438
//	}
2439 2286 tao
2440 5014 daigle
//	/**
2441
//	 * Method for writing replication messages to a log file specified in
2442
//	 * metacat.properties
2443
//	 */
2444
//	public static void replErrorLog(String message) {
2445
//		try {
2446
//			FileOutputStream fos = new FileOutputStream(PropertyService
2447
//					.getProperty("replication.logdir")
2448
//					+ "/metacatreplicationerror.log", true);
2449
//			PrintWriter pw = new PrintWriter(fos);
2450
//			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
2451
//			java.util.Date localtime = new java.util.Date();
2452
//			String dateString = formatter.format(localtime);
2453
//			dateString += " :: " + message;
2454
//			//time stamp each entry
2455
//			pw.println(dateString);
2456
//			pw.flush();
2457
//		} catch (Exception e) {
2458
//			logReplication.error("error writing to replication error log from "
2459
//					+ "MetacatReplication.replErrorLog: " + e.getMessage());
2460
//			//e.printStackTrace(System.out);
2461
//		}
2462
//	}
2463 2286 tao
2464 5014 daigle
	/**
2465
	 * Returns true if the replicate field for server in xml_replication is 1.
2466
	 * Returns false otherwise
2467 4080 daigle
	 */
2468 5014 daigle
	public static boolean replToServer(String server) {
2469
		DBConnection dbConn = null;
2470
		int serialNumber = -1;
2471
		PreparedStatement pstmt = null;
2472 4080 daigle
		try {
2473 5014 daigle
			dbConn = DBConnectionPool.getDBConnection("MetacatReplication.repltoServer");
2474
			serialNumber = dbConn.getCheckOutSerialNumber();
2475
			pstmt = dbConn.prepareStatement("select replicate from "
2476 6595 leinfelder
					+ "xml_replication where server like ? ");
2477
			pstmt.setString(1, server);
2478 5014 daigle
			pstmt.execute();
2479
			ResultSet rs = pstmt.getResultSet();
2480
			boolean tablehasrows = rs.next();
2481
			if (tablehasrows) {
2482
				int i = rs.getInt(1);
2483
				if (i == 1) {
2484
					pstmt.close();
2485
					//conn.close();
2486
					return true;
2487
				} else {
2488
					pstmt.close();
2489
					//conn.close();
2490
					return false;
2491
				}
2492
			}
2493
		} catch (SQLException sqle) {
2494
			logMetacat.error("ReplicationService.replToServer - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2495
			logReplication.error("ReplicationService.replToServer - SQL error in MetacatReplication.replToServer: "
2496
					+ sqle.getMessage());
2497
		} finally {
2498
			try {
2499
				pstmt.close();
2500
				//conn.close();
2501
			}//try
2502
			catch (Exception ee) {
2503
				logMetacat.error("ReplicationService.replToServer - " + ReplicationService.METACAT_REPL_ERROR_MSG);
2504
				logReplication.error("ReplicationService.replToServer - Error in MetacatReplication.replToServer: "
2505
						+ ee.getMessage());
2506
			}//catch
2507
			finally {
2508
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2509
			}//finally
2510
		}//finally
2511
		return false;
2512
		//the default if this server does not exist is to not replicate to it.
2513 4080 daigle
	}
2514 2286 tao
2515 522 berkley
}