Project

General

Profile

1 522 berkley
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class to asyncronously do delta-T replication checking
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 2286 tao
27 5014 daigle
package edu.ucsb.nceas.metacat.replication;
28 522 berkley
29 5014 daigle
import edu.ucsb.nceas.metacat.CatalogMessageHandler;
30
import edu.ucsb.nceas.metacat.DBUtil;
31
import edu.ucsb.nceas.metacat.DocInfoHandler;
32
import edu.ucsb.nceas.metacat.DocumentImpl;
33
import edu.ucsb.nceas.metacat.DocumentImplWrapper;
34
import edu.ucsb.nceas.metacat.EventLog;
35 6001 cjones
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
36 5089 daigle
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile;
37 5098 daigle
import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessDAO;
38 6001 cjones
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException;
39 5014 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
40
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
41
import edu.ucsb.nceas.metacat.database.DatabaseService;
42 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
43 5014 daigle
import edu.ucsb.nceas.metacat.shared.HandlerException;
44 4698 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
45 6102 leinfelder
import edu.ucsb.nceas.metacat.util.ReplicationUtil;
46 5324 berkley
import edu.ucsb.nceas.metacat.IdentifierManager;
47 4080 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
48
49 522 berkley
import java.sql.*;
50
import java.util.*;
51 2555 tao
import java.util.Date;
52 522 berkley
import java.io.*;
53
import java.net.*;
54 543 berkley
import java.text.*;
55 2663 sgarg
56
import org.apache.log4j.Logger;
57 6366 leinfelder
import org.dataone.service.types.v1.SystemMetadata;
58 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
59 522 berkley
import org.xml.sax.ContentHandler;
60
import org.xml.sax.ErrorHandler;
61
import org.xml.sax.InputSource;
62 5014 daigle
import org.xml.sax.SAXException;
63 522 berkley
import org.xml.sax.XMLReader;
64
import org.xml.sax.helpers.XMLReaderFactory;
65 561 berkley
import org.xml.sax.helpers.DefaultHandler;
66 522 berkley
67 561 berkley
68
69 522 berkley
/**
70
 * This class handles deltaT replication checking.  Whenever this TimerTask
71
 * is fired it checks each server in xml_replication for updates and updates
72
 * the local db as needed.
73
 */
74
public class ReplicationHandler extends TimerTask
75
{
76 573 berkley
  int serverCheckCode = 1;
77 2286 tao
  ReplicationServerList serverList = null;
78 2573 tao
  //PrintWriter out;
79 4698 daigle
//  private static final AbstractDatabase dbAdapter = MetacatUtil.dbAdapter;
80 5014 daigle
  private static Logger logReplication = Logger.getLogger("ReplicationLogging");
81 2663 sgarg
  private static Logger logMetacat = Logger.getLogger(ReplicationHandler.class);
82 5392 berkley
  private static Logger logD1 = Logger.getLogger("DataOneLogger");
83
84 2725 tao
  private static int DOCINSERTNUMBER = 1;
85
  private static int DOCERRORNUMBER  = 1;
86
  private static int REVINSERTNUMBER = 1;
87
  private static int REVERRORNUMBER  = 1;
88 5175 daigle
89
  private static int _xmlDocQueryCount = 0;
90
  private static int _xmlRevQueryCount = 0;
91
  private static long _xmlDocQueryTime = 0;
92
  private static long _xmlRevQueryTime = 0;
93
94
95 2573 tao
  public ReplicationHandler()
96 522 berkley
  {
97 2573 tao
    //this.out = o;
98 1292 tao
    serverList = new ReplicationServerList();
99 522 berkley
  }
100 2286 tao
101 2573 tao
  public ReplicationHandler(int serverCheckCode)
102 573 berkley
  {
103 2573 tao
    //this.out = o;
104 573 berkley
    this.serverCheckCode = serverCheckCode;
105 1292 tao
    serverList = new ReplicationServerList();
106 573 berkley
  }
107 2286 tao
108 522 berkley
  /**
109 2286 tao
   * Method that implements TimerTask.run().  It runs whenever the timer is
110 522 berkley
   * fired.
111
   */
112
  public void run()
113
  {
114
    //find out the last_checked time of each server in the server list and
115 2286 tao
    //send a query to each server to see if there are any documents in
116 522 berkley
    //xml_documents with an update_date > last_checked
117 5014 daigle
118 1032 tao
      //if serverList is null, metacat don't need to replication
119
      if (serverList==null||serverList.isEmpty())
120
      {
121
        return;
122
      }
123 1292 tao
      updateCatalog();
124
      update();
125 1217 tao
      //conn.close();
126 522 berkley
  }
127 2286 tao
128 522 berkley
  /**
129 5175 daigle
   * Method that uses revision tagging for replication instead of update_date.
130 577 berkley
   */
131 1292 tao
  private void update()
132 577 berkley
  {
133 5175 daigle
134
	  _xmlDocQueryCount = 0;
135
	  _xmlRevQueryCount = 0;
136
	  _xmlDocQueryTime = 0;
137
	  _xmlRevQueryTime = 0;
138 577 berkley
    /*
139
     Pseudo-algorithm
140
     - request a doc list from each server in xml_replication
141 2286 tao
     - check the rev number of each of those documents agains the
142 577 berkley
       documents in the local database
143
     - pull any documents that have a lesser rev number on the local server
144
       from the remote server
145
     - delete any documents that still exist in the local xml_documents but
146
       are in the deletedDocuments tag of the remote host response.
147
     - update last_checked to keep track of the last time it was checked.
148 2286 tao
       (this info is theoretically not needed using this system but probably
149 577 berkley
       should be kept anyway)
150
    */
151 2286 tao
152
    ReplicationServer replServer = null; // Variable to store the
153
                                        // ReplicationServer got from
154 1292 tao
                                        // Server list
155 2298 tao
    String server = null; // Variable to store server name
156 5014 daigle
//    String update;
157
    Vector<String> responses = new Vector<String>();
158 577 berkley
    URL u;
159 5175 daigle
    long replicationStartTime = System.currentTimeMillis();
160
    long timeToGetServerList = 0;
161 3898 tao
162 1585 tao
    //Check for every server in server list to get updated list and put
163
    // them in to response
164 5175 daigle
    long startTimeToGetServers = System.currentTimeMillis();
165 1585 tao
    for (int i=0; i<serverList.size(); i++)
166
    {
167 1292 tao
        // Get ReplicationServer object from server list
168
        replServer = serverList.serverAt(i);
169
        // Get server name from ReplicationServer object
170 2578 tao
        server = replServer.getServerName().trim();
171 1585 tao
        String result = null;
172 5014 daigle
        logReplication.info("ReplicationHandler.update - full update started to: " + server);
173 1292 tao
        // Send command to that server to get updated docid information
174
        try
175
        {
176 1585 tao
          u = new URL("https://" + server + "?server="
177 4698 daigle
          +MetacatUtil.getLocalReplicationServerName()+"&action=update");
178 5014 daigle
          logReplication.info("ReplicationHandler.update - Sending infomation " +u.toString());
179
          result = ReplicationService.getURLContent(u);
180 1585 tao
        }
181 1292 tao
        catch (Exception e)
182
        {
183 5014 daigle
          logMetacat.error("ReplicationHandler.update - " + ReplicationService.METACAT_REPL_ERROR_MSG);
184
          logReplication.error( "ReplicationHandler.update - Failed to get updated doc list "+
185 2663 sgarg
                       "for server " + server + " because "+e.getMessage());
186 1292 tao
          continue;
187 1585 tao
        }
188 2286 tao
189 5175 daigle
        //logReplication.info("ReplicationHandler.update - docid: "+server+" "+result);
190 1292 tao
        //check if result have error or not, if has skip it.
191 1609 tao
        if (result.indexOf("<error>")!=-1 && result.indexOf("</error>")!=-1)
192 1102 tao
        {
193 5014 daigle
          logMetacat.error("ReplicationHandler.update - " + ReplicationService.METACAT_REPL_ERROR_MSG);
194
          logReplication.error( "ReplicationHandler.update - Failed to get updated doc list "+
195 2663 sgarg
                       "for server " + server + " because "+result);
196 1102 tao
          continue;
197
        }
198 1585 tao
        //Add result to vector
199 577 berkley
        responses.add(result);
200 1585 tao
    }
201 5175 daigle
    timeToGetServerList = System.currentTimeMillis() - startTimeToGetServers;
202 2286 tao
203 1585 tao
    //make sure that there is updated file list
204
    //If response is null, metacat don't need do anything
205
    if (responses==null || responses.isEmpty())
206
    {
207 5014 daigle
    	logMetacat.error("ReplicationHandler.update - " + ReplicationService.METACAT_REPL_ERROR_MSG);
208
        logReplication.info( "ReplicationHandler.update - No updated doc list for "+
209 1585 tao
                           "every server and failed to replicate");
210 1032 tao
        return;
211 1585 tao
    }
212 2286 tao
213
214 5175 daigle
    //logReplication.info("ReplicationHandler.update - Responses from remote metacat about updated "+
215
    //               "document information: "+ responses.toString());
216
217
    long totalServerListParseTime = 0;
218 1585 tao
    // go through response vector(it contains updated vector and delete vector
219
    for(int i=0; i<responses.size(); i++)
220 2286 tao
    {
221 5175 daigle
    	long startServerListParseTime = System.currentTimeMillis();
222 3898 tao
    	XMLReader parser;
223
    	ReplMessageHandler message = new ReplMessageHandler();
224
    	try
225
        {
226
          parser = initParser(message);
227
        }
228
        catch (Exception e)
229
        {
230 5014 daigle
          logMetacat.error("ReplicationHandler.update - " + ReplicationService.METACAT_REPL_ERROR_MSG);
231
          logReplication.error("ReplicationHandler.update - Failed to replicate becaue couldn't " +
232 3898 tao
                                " initParser for message and " +e.getMessage());
233
           // stop replication
234
           return;
235
        }
236
237 1585 tao
        try
238
        {
239
          parser.parse(new InputSource(
240 577 berkley
                     new StringReader(
241
                     (String)(responses.elementAt(i)))));
242 1585 tao
        }
243
        catch(Exception e)
244
        {
245 5014 daigle
          logMetacat.error("ReplicationHandler.update - " + ReplicationService.METACAT_REPL_ERROR_MSG);
246
          logReplication.error("ReplicationHandler.update - Couldn't parse one responses "+
247 2663 sgarg
                                   "because "+ e.getMessage());
248 1585 tao
          continue;
249
        }
250 1037 tao
        //v is the list of updated documents
251 5014 daigle
        Vector<Vector<String>> updateList = new Vector<Vector<String>>(message.getUpdatesVect());
252
        logReplication.info("ReplicationHandler.update - The document list size is "+updateList.size()+ " from "+message.getServerName());
253 1037 tao
        //d is the list of deleted documents
254 5014 daigle
        Vector<Vector<String>> deleteList = new Vector<Vector<String>>(message.getDeletesVect());
255
        logReplication.info("ReplicationHandler.update - Update vector size: "+ updateList.size()+" from "+message.getServerName());
256
        logReplication.info("ReplicationHandler.update - Delete vector size: "+ deleteList.size()+" from "+message.getServerName());
257
        logReplication.info("ReplicationHandler.update - The delete document list size is "+deleteList.size()+" from "+message.getServerName());
258 1585 tao
        // go though every element in updated document vector
259 2608 tao
        handleDocList(updateList, DocumentImpl.DOCUMENTTABLE);
260 1037 tao
        //handle deleted docs
261 1585 tao
        for(int k=0; k<deleteList.size(); k++)
262 577 berkley
        { //delete the deleted documents;
263 5014 daigle
          Vector<String> w = new Vector<String>(deleteList.elementAt(k));
264 1585 tao
          String docId = (String)w.elementAt(0);
265
          try
266 579 berkley
          {
267 2298 tao
            handleDeleteSingleDocument(docId, server);
268 579 berkley
          }
269 1585 tao
          catch (Exception ee)
270
          {
271
            continue;
272
          }
273 1037 tao
        }//for delete docs
274 2608 tao
275
        // handle replicate doc in xml_revision
276 5014 daigle
        Vector<Vector<String>> revisionList = new Vector<Vector<String>>(message.getRevisionsVect());
277
        logReplication.info("ReplicationHandler.update - The revision document list size is "+revisionList.size()+ " from "+message.getServerName());
278 2608 tao
        handleDocList(revisionList, DocumentImpl.REVISIONTABLE);
279 2725 tao
        DOCINSERTNUMBER = 1;
280
        DOCERRORNUMBER  = 1;
281
        REVINSERTNUMBER = 1;
282
        REVERRORNUMBER  = 1;
283 5175 daigle
284 6118 leinfelder
        // handle system metadata
285
        Vector<Vector<String>> systemMetadataList = message.getSystemMetadataVect();
286
        for(int k = 0; k < systemMetadataList.size(); k++) {
287
        	Vector<String> w = systemMetadataList.elementAt(k);
288
        	String guid = (String) w.elementAt(0);
289
        	String remoteserver = (String) w.elementAt(1);
290
        	try {
291
        		handleSystemMetadata(remoteserver, guid);
292
        	}
293
        	catch (Exception ee) {
294
        		logMetacat.error("Error replicating system metedata for guid: " + guid, ee);
295
        		continue;
296
        	}
297
        }
298
299 5175 daigle
        totalServerListParseTime += (System.currentTimeMillis() - startServerListParseTime);
300 1585 tao
    }//for response
301 2286 tao
302 1585 tao
    //updated last_checked
303
    for (int i=0;i<serverList.size(); i++)
304
    {
305
       // Get ReplicationServer object from server list
306
       replServer = serverList.serverAt(i);
307
       try
308
       {
309
         updateLastCheckTimeForSingleServer(replServer);
310
       }
311
       catch(Exception e)
312
       {
313
         continue;
314
       }
315
    }//for
316 5175 daigle
317
    long replicationEndTime = System.currentTimeMillis();
318
    logMetacat.debug("ReplicationHandler.update - Total replication time: " +
319
    		(replicationEndTime - replicationStartTime));
320
    logMetacat.debug("ReplicationHandler.update - time to get server list: " +
321
    		timeToGetServerList);
322
    logMetacat.debug("ReplicationHandler.update - server list parse time: " +
323
    		totalServerListParseTime);
324
    logMetacat.debug("ReplicationHandler.update - 'in xml_documents' total query count: " +
325
    		_xmlDocQueryCount);
326
    logMetacat.debug("ReplicationHandler.update - 'in xml_documents' total query time: " +
327
    		_xmlDocQueryTime + " ms");
328
    logMetacat.debug("ReplicationHandler.update - 'in xml_revisions' total query count: " +
329
    		_xmlRevQueryCount);
330
    logMetacat.debug("ReplicationHandler.update - 'in xml_revisions' total query time: " +
331
    		_xmlRevQueryTime + " ms");;
332 2286 tao
333 1585 tao
  }//update
334 2286 tao
335 1585 tao
  /* Handle replicate single xml document*/
336 2286 tao
  private void handleSingleXMLDocument(String remoteserver, String actions,
337 2641 tao
                                       String accNumber, String tableName)
338 5014 daigle
               throws HandlerException
339 1585 tao
  {
340
    DBConnection dbConn = null;
341
    int serialNumber = -1;
342
    try
343
    {
344
      // Get DBConnection from pool
345
      dbConn=DBConnectionPool.
346
                  getDBConnection("ReplicationHandler.handleSingleXMLDocument");
347
      serialNumber=dbConn.getCheckOutSerialNumber();
348
      //if the document needs to be updated or inserted, this is executed
349 1600 tao
      String readDocURLString = "https://" + remoteserver + "?server="+
350 4698 daigle
              MetacatUtil.getLocalReplicationServerName()+"&action=read&docid="+accNumber;
351
      readDocURLString = MetacatUtil.replaceWhiteSpaceForURL(readDocURLString);
352 1600 tao
      URL u = new URL(readDocURLString);
353 2286 tao
354 1585 tao
      // Get docid content
355 5014 daigle
      String newxmldoc = ReplicationService.getURLContent(u);
356 1585 tao
      // If couldn't get skip it
357 1609 tao
      if ( newxmldoc.indexOf("<error>")!= -1 && newxmldoc.indexOf("</error>")!=-1)
358 1292 tao
      {
359 5014 daigle
         throw new HandlerException("ReplicationHandler.handleSingleXMLDocument - " + newxmldoc);
360 1585 tao
      }
361 5014 daigle
      //logReplication.info("xml documnet:");
362
      //logReplication.info(newxmldoc);
363 2286 tao
364 1585 tao
      // Try get the docid info from remote server
365
      DocInfoHandler dih = new DocInfoHandler();
366
      XMLReader docinfoParser = initParser(dih);
367 2286 tao
      String docInfoURLStr = "https://" + remoteserver +
368 4698 daigle
                       "?server="+MetacatUtil.getLocalReplicationServerName()+
369 2641 tao
                       "&action=getdocumentinfo&docid="+accNumber;
370 4698 daigle
      docInfoURLStr = MetacatUtil.replaceWhiteSpaceForURL(docInfoURLStr);
371 1600 tao
      URL docinfoUrl = new URL(docInfoURLStr);
372 6102 leinfelder
      logReplication.info("ReplicationHandler.handleSingleXMLDocument - Sending message: " + docinfoUrl.toString());
373 5014 daigle
      String docInfoStr = ReplicationService.getURLContent(docinfoUrl);
374 6102 leinfelder
375
      // strip out the system metadata portion
376
      String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
377
   	  docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
378
379 1585 tao
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
380 5014 daigle
      Hashtable<String, String> docinfoHash = dih.getDocInfo();
381 1585 tao
      // Get home server of the docid
382 5014 daigle
      String docHomeServer = docinfoHash.get("home_server");
383
      logReplication.info("ReplicationHandler.handleSingleXMLDocument - doc home server in repl: "+docHomeServer);
384
      String createdDate = docinfoHash.get("date_created");
385
      String updatedDate = docinfoHash.get("date_updated");
386 1585 tao
      //docid should include rev number too
387 4212 daigle
      /*String accnum=docId+util.getProperty("document.accNumSeparator")+
388 2641 tao
                                              (String)docinfoHash.get("rev");*/
389 5014 daigle
      logReplication.info("ReplicationHandler.handleSingleXMLDocument - docid in repl: "+accNumber);
390
      String docType = docinfoHash.get("doctype");
391
      logReplication.info("ReplicationHandler.handleSingleXMLDocument - doctype in repl: "+docType);
392 2286 tao
393 1585 tao
      String parserBase = null;
394
      // this for eml2 and we need user eml2 parser
395 2169 sgarg
      if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
396 1585 tao
      {
397 2163 tao
         parserBase = DocumentImpl.EML200;
398 1585 tao
      }
399 2286 tao
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE))
400
      {
401
        parserBase = DocumentImpl.EML200;
402
      }
403
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE))
404
      {
405
        parserBase = DocumentImpl.EML210;
406
      }
407 5709 leinfelder
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_1_1NAMESPACE))
408
      {
409
        parserBase = DocumentImpl.EML210;
410
      }
411 1585 tao
      // Write the document into local host
412
      DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false);
413 2286 tao
      String newDocid = wrapper.writeReplication(dbConn,
414 5195 daigle
                              newxmldoc,
415 5014 daigle
                              docinfoHash.get("public_access"),
416 1585 tao
                              null,  /* the dtd text */
417 2286 tao
                              actions,
418 2641 tao
                              accNumber,
419 6015 leinfelder
                              null, //docinfoHash.get("user_owner"),
420 1585 tao
                              null, /* null for groups[] */
421 2286 tao
                              docHomeServer,
422 2624 tao
                              remoteserver, tableName, true,// true is for time replication
423
                              createdDate,
424 3230 tao
                              updatedDate);
425 4419 leinfelder
426 6015 leinfelder
      //set the user information
427
      String user = (String) docinfoHash.get("user_owner");
428
      String updated = (String) docinfoHash.get("user_updated");
429
      ReplicationService.updateUserOwner(dbConn, accNumber, user, updated);
430
431 5098 daigle
      //process extra access rules
432
      Vector<XMLAccessDAO> xmlAccessDAOList = dih.getAccessControlList();
433
      if (xmlAccessDAOList != null) {
434
      	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(accNumber);
435
      	for (XMLAccessDAO xmlAccessDAO : xmlAccessDAOList) {
436
      		if (!acfsf.accessControlExists(xmlAccessDAO)) {
437
      			acfsf.insertPermissions(xmlAccessDAO);
438
      		}
439 4419 leinfelder
          }
440
      }
441
442 6102 leinfelder
      // process system metadata
443
      if (systemMetadataXML != null) {
444
    	  SystemMetadata sysMeta =
445 6367 leinfelder
    		  TypeMarshaller.unmarshalTypeFromStream(
446 6102 leinfelder
    				  SystemMetadata.class,
447
    				  new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
448
    	  String guid = sysMeta.getIdentifier().getValue();
449 6099 leinfelder
    	  if (!IdentifierManager.getInstance().identifierExists(guid)) {
450 6102 leinfelder
    		  logReplication.debug("Creating system metadata and guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
451 6099 leinfelder
    		  IdentifierManager.getInstance().createMapping(guid, docinfoHash.get("docid"));
452 6102 leinfelder
    		  IdentifierManager.getInstance().createSystemMetadata(sysMeta);
453 6099 leinfelder
    	  } else {
454
    		  logReplication.debug("Updating guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
455
    		  IdentifierManager.getInstance().updateMapping(guid, docinfoHash.get("docid"));
456
    	  }
457
          IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
458 5457 berkley
      }
459
460 5014 daigle
      logReplication.info("ReplicationHandler.handleSingleXMLDocument - Successfully replicated doc " + accNumber);
461 2725 tao
      if (tableName.equals(DocumentImpl.DOCUMENTTABLE))
462
      {
463 5014 daigle
        logReplication.info("ReplicationHandler.handleSingleXMLDocument - " + DOCINSERTNUMBER + " Wrote xml doc " + accNumber +
464 2725 tao
                                     " into "+tableName + " from " +
465 1585 tao
                                         remoteserver);
466 2725 tao
        DOCINSERTNUMBER++;
467
      }
468
      else
469
      {
470 5014 daigle
          logReplication.info("ReplicationHandler.handleSingleXMLDocument - " +REVINSERTNUMBER + " Wrote xml doc " + accNumber +
471 2725 tao
                  " into "+tableName + " from " +
472
                      remoteserver);
473
          REVINSERTNUMBER++;
474
      }
475 3234 tao
      String ip = getIpFromURL(u);
476 5014 daigle
      EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, accNumber, actions);
477 2725 tao
478 2286 tao
479
    }//try
480 577 berkley
    catch(Exception e)
481
    {
482 2725 tao
483
        if (tableName.equals(DocumentImpl.DOCUMENTTABLE))
484
        {
485 5014 daigle
        	logMetacat.error("ReplicationHandler.handleSingleXMLDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
486
        	logReplication.error("ReplicationHandler.handleSingleXMLDocument - " +DOCERRORNUMBER + " Failed to write xml doc " + accNumber +
487 2725 tao
                                       " into "+tableName + " from " +
488
                                           remoteserver + " because "+e.getMessage());
489
          DOCERRORNUMBER++;
490
        }
491
        else
492
        {
493 5014 daigle
        	logMetacat.error("ReplicationHandler.handleSingleXMLDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
494
        	logReplication.error("ReplicationHandler.handleSingleXMLDocument - " +REVERRORNUMBER + " Failed to write xml doc " + accNumber +
495 2725 tao
                    " into "+tableName + " from " +
496
                        remoteserver +" because "+e.getMessage());
497
            REVERRORNUMBER++;
498
        }
499 5014 daigle
        logMetacat.error("ReplicationHandler.handleSingleXMLDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
500
        logReplication.error("ReplicationHandler.handleSingleXMLDocument - Failed to write doc " + accNumber +
501 2663 sgarg
                                      " into db because " +e.getMessage());
502 5014 daigle
      throw new HandlerException("ReplicationHandler.handleSingleXMLDocument - generic exception "
503
    		  + "writing Replication: " +e.getMessage());
504 577 berkley
    }
505 667 berkley
    finally
506
    {
507 1585 tao
       //return DBConnection
508
       DBConnectionPool.returnDBConnection(dbConn, serialNumber);
509
    }//finally
510 5392 berkley
    logD1.info("replication.create localId:" + accNumber);
511 1585 tao
  }
512 2286 tao
513
514
515 1585 tao
  /* Handle replicate single xml document*/
516 2286 tao
  private void handleSingleDataFile(String remoteserver, String actions,
517 2641 tao
                                    String accNumber, String tableName)
518 5014 daigle
               throws HandlerException
519 1585 tao
  {
520 5014 daigle
    logReplication.info("ReplicationHandler.handleSingleDataFile - Try to replicate data file: " + accNumber);
521 1585 tao
    DBConnection dbConn = null;
522
    int serialNumber = -1;
523
    try
524
    {
525
      // Get DBConnection from pool
526
      dbConn=DBConnectionPool.
527
                  getDBConnection("ReplicationHandler.handleSinlgeDataFile");
528
      serialNumber=dbConn.getCheckOutSerialNumber();
529
      // Try get docid info from remote server
530
      DocInfoHandler dih = new DocInfoHandler();
531
      XMLReader docinfoParser = initParser(dih);
532 2286 tao
      String docInfoURLString = "https://" + remoteserver +
533 4698 daigle
                  "?server="+MetacatUtil.getLocalReplicationServerName()+
534 2641 tao
                  "&action=getdocumentinfo&docid="+accNumber;
535 4698 daigle
      docInfoURLString = MetacatUtil.replaceWhiteSpaceForURL(docInfoURLString);
536 1600 tao
      URL docinfoUrl = new URL(docInfoURLString);
537 2286 tao
538 5014 daigle
      String docInfoStr = ReplicationService.getURLContent(docinfoUrl);
539 6102 leinfelder
540
      // strip out the system metadata portion
541
      String systemMetadataXML = ReplicationUtil.getSystemMetadataContent(docInfoStr);
542
   	  docInfoStr = ReplicationUtil.getContentWithoutSystemMetadata(docInfoStr);
543
544 1585 tao
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
545 5014 daigle
      Hashtable<String, String> docinfoHash = dih.getDocInfo();
546 6015 leinfelder
547 1585 tao
      // Get docid name (such as acl or dataset)
548 5014 daigle
      String docName = docinfoHash.get("docname");
549 2286 tao
      // Get doc type (eml public id)
550 5014 daigle
      String docType = docinfoHash.get("doctype");
551 1585 tao
      // Get docid home sever. it might be different to remoteserver
552 5175 daigle
      // because of hub feature
553 5014 daigle
      String docHomeServer = docinfoHash.get("home_server");
554
      String createdDate = docinfoHash.get("date_created");
555
      String updatedDate = docinfoHash.get("date_updated");
556 1585 tao
      //docid should include rev number too
557 4212 daigle
      /*String accnum=docId+util.getProperty("document.accNumSeparator")+
558 2641 tao
                                              (String)docinfoHash.get("rev");*/
559 2286 tao
560 4080 daigle
      String datafilePath = PropertyService.getProperty("application.datafilepath");
561 1585 tao
      // Get data file content
562 1600 tao
      String readDataURLString = "https://" + remoteserver + "?server="+
563 4698 daigle
                                        MetacatUtil.getLocalReplicationServerName()+
564 2641 tao
                                            "&action=readdata&docid="+accNumber;
565 4698 daigle
      readDataURLString = MetacatUtil.replaceWhiteSpaceForURL(readDataURLString);
566 1600 tao
      URL u = new URL(readDataURLString);
567 2286 tao
      InputStream input = u.openStream();
568 1585 tao
      //register data file into xml_documents table and wite data file
569
      //into file system
570 1600 tao
      if ( input != null)
571 667 berkley
      {
572 2286 tao
        DocumentImpl.writeDataFileInReplication(input,
573 2608 tao
                                                datafilePath,
574
                                                docName,docType,
575 6015 leinfelder
                                                accNumber,
576
                                                null,
577 2608 tao
                                                docHomeServer,
578
                                                remoteserver,
579
                                                tableName,
580 2624 tao
                                                true, //true means timed replication
581
                                                createdDate,
582 3230 tao
                                                updatedDate);
583 2624 tao
584 6015 leinfelder
        //set the user information
585
        String user = (String) docinfoHash.get("user_owner");
586
		String updated = (String) docinfoHash.get("user_updated");
587
        ReplicationService.updateUserOwner(dbConn, accNumber, user, updated);
588
589 4419 leinfelder
        //process extra access rules
590 5098 daigle
        Vector<XMLAccessDAO> xmlAccessDAOList = dih.getAccessControlList();
591
        if (xmlAccessDAOList != null) {
592
        	AccessControlForSingleFile acfsf = new AccessControlForSingleFile(accNumber);
593
        	for (XMLAccessDAO xmlAccessDAO : xmlAccessDAOList) {
594
        		if (!acfsf.accessControlExists(xmlAccessDAO)) {
595
        			acfsf.insertPermissions(xmlAccessDAO);
596
        		}
597 4419 leinfelder
            }
598
        }
599
600 6099 leinfelder
        //process guid
601 6102 leinfelder
     // process system metadata
602
        if (systemMetadataXML != null) {
603
      	  SystemMetadata sysMeta =
604 6367 leinfelder
      		TypeMarshaller.unmarshalTypeFromStream(
605 6102 leinfelder
      				  SystemMetadata.class,
606
      				  new ByteArrayInputStream(systemMetadataXML.getBytes("UTF-8")));
607
      	  String guid = sysMeta.getIdentifier().getValue();
608 6099 leinfelder
      	  if (!IdentifierManager.getInstance().identifierExists(guid)) {
609 6102 leinfelder
      		  logReplication.debug("Creating system metadata and guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
610 6099 leinfelder
      		  IdentifierManager.getInstance().createMapping(guid, docinfoHash.get("docid"));
611 6102 leinfelder
      		  IdentifierManager.getInstance().createSystemMetadata(sysMeta);
612 6099 leinfelder
      	  } else {
613
      		  logReplication.debug("Updating guid/docid mapping for docid " + docinfoHash.get("docid") + " and guid: " + guid);
614
      		  IdentifierManager.getInstance().updateMapping(guid, docinfoHash.get("docid"));
615
      	  }
616
            IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
617
        }
618
619 5014 daigle
        logReplication.info("ReplicationHandler.handleSingleDataFile - Successfully to write datafile " + accNumber);
620 2725 tao
        /*MetacatReplication.replLog("wrote datafile " + accNumber + " from " +
621 5175 daigle
                                    remote server);*/
622 2725 tao
        if (tableName.equals(DocumentImpl.DOCUMENTTABLE))
623
        {
624 5014 daigle
          logReplication.info("ReplicationHandler.handleSingleDataFile - " + DOCINSERTNUMBER + " Wrote data file" + accNumber +
625 2725 tao
                                       " into "+tableName + " from " +
626
                                           remoteserver);
627
          DOCINSERTNUMBER++;
628
        }
629
        else
630
        {
631 5014 daigle
            logReplication.info("ReplicationHandler.handleSingleDataFile - " + REVINSERTNUMBER + " Wrote data file" + accNumber +
632 2725 tao
                    " into "+tableName + " from " +
633
                        remoteserver);
634
            REVINSERTNUMBER++;
635
        }
636 3234 tao
        String ip = getIpFromURL(u);
637 5014 daigle
        EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, accNumber, actions);
638 2725 tao
639 1585 tao
      }//if
640
      else
641 1217 tao
      {
642 5014 daigle
         logReplication.info("ReplicationHandler.handleSingleDataFile - Couldn't open the data file: " + accNumber);
643
         throw new HandlerException("ReplicationHandler.handleSingleDataFile - Couldn't open the data file: " + accNumber);
644 1585 tao
      }//else
645 2286 tao
646
    }//try
647 1585 tao
    catch(Exception e)
648
    {
649 5175 daigle
      /*MetacatReplication.replErrorLog("Failed to try wrote data file " + accNumber +
650 2725 tao
                                      " because " +e.getMessage());*/
651
      if (tableName.equals(DocumentImpl.DOCUMENTTABLE))
652
      {
653 5014 daigle
    	logMetacat.error("ReplicationHandler.handleSingleDataFile - " + ReplicationService.METACAT_REPL_ERROR_MSG);
654
    	logReplication.error("ReplicationHandler.handleSingleDataFile - " + DOCERRORNUMBER + " Failed to write data file " + accNumber +
655
                                     " into " + tableName + " from " +
656
                                         remoteserver + " because " + e.getMessage());
657 2725 tao
        DOCERRORNUMBER++;
658
      }
659
      else
660
      {
661 5014 daigle
    	  logMetacat.error("ReplicationHandler.handleSingleDataFile - " + ReplicationService.METACAT_REPL_ERROR_MSG);
662
    	  logReplication.error("ReplicationHandler.handleSingleDataFile - " + REVERRORNUMBER + " Failed to write data file" + accNumber +
663
                  " into " + tableName + " from " +
664
                      remoteserver +" because "+ e.getMessage());
665 2725 tao
          REVERRORNUMBER++;
666
      }
667 5014 daigle
      logMetacat.error("ReplicationHandler.handleSingleDataFile - " + ReplicationService.METACAT_REPL_ERROR_MSG);
668
      logReplication.error("ReplicationHandler.handleSingleDataFile - Failed to try wrote datafile " + accNumber +
669
                                      " because " + e.getMessage());
670
      throw new HandlerException("ReplicationHandler.handleSingleDataFile - generic exception "
671
    		  + "writing Replication: " + e.getMessage());
672 1585 tao
    }
673
    finally
674
    {
675
       //return DBConnection
676
       DBConnectionPool.returnDBConnection(dbConn, serialNumber);
677
    }//finally
678 5392 berkley
    logD1.info("replication.create localId:" + accNumber);
679 1585 tao
  }
680 2286 tao
681
682
683 1585 tao
  /* Handle delete single document*/
684 2298 tao
  private void handleDeleteSingleDocument(String docId, String notifyServer)
685 5014 daigle
               throws HandlerException
686 1585 tao
  {
687 5014 daigle
    logReplication.info("ReplicationHandler.handleDeleteSingleDocument - Try delete doc: "+docId);
688 1585 tao
    DBConnection dbConn = null;
689
    int serialNumber = -1;
690
    try
691
    {
692
      // Get DBConnection from pool
693
      dbConn=DBConnectionPool.
694
                  getDBConnection("ReplicationHandler.handleDeleteSingleDoc");
695
      serialNumber=dbConn.getCheckOutSerialNumber();
696
      if(!alreadyDeleted(docId))
697 1217 tao
      {
698 2286 tao
699 1585 tao
         //because delete method docid should have rev number
700
         //so we just add one for it. This rev number is no sence.
701 4212 daigle
         String accnum=docId+PropertyService.getProperty("document.accNumSeparator")+"1";
702 3230 tao
         DocumentImpl.delete(accnum, null, null, notifyServer);
703 5014 daigle
         logReplication.info("ReplicationHandler.handleDeleteSingleDocument - Successfully deleted doc " + docId);
704
         logReplication.info("ReplicationHandler.handleDeleteSingleDocument - Doc " + docId + " deleted");
705 3234 tao
         URL u = new URL("https://"+notifyServer);
706
         String ip = getIpFromURL(u);
707 5014 daigle
         EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, docId, "delete");
708 1585 tao
      }
709 2286 tao
710
    }//try
711 6001 cjones
    catch(McdbDocNotFoundException e)
712
    {
713
      logMetacat.error("ReplicationHandler.handleDeleteSingleDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
714
      logReplication.error("ReplicationHandler.handleDeleteSingleDocument - Failed to delete doc " + docId +
715
                                 " in db because because " + e.getMessage());
716
      throw new HandlerException("ReplicationHandler.handleDeleteSingleDocument - generic exception "
717
    		  + "when handling document: " + e.getMessage());
718
    }
719
    catch(InsufficientKarmaException e)
720
    {
721
      logMetacat.error("ReplicationHandler.handleDeleteSingleDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
722
      logReplication.error("ReplicationHandler.handleDeleteSingleDocument - Failed to delete doc " + docId +
723
                                 " in db because because " + e.getMessage());
724
      throw new HandlerException("ReplicationHandler.handleDeleteSingleDocument - generic exception "
725
    		  + "when handling document: " + e.getMessage());
726
    }
727
    catch(SQLException e)
728
    {
729
      logMetacat.error("ReplicationHandler.handleDeleteSingleDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
730
      logReplication.error("ReplicationHandler.handleDeleteSingleDocument - Failed to delete doc " + docId +
731
                                 " in db because because " + e.getMessage());
732
      throw new HandlerException("ReplicationHandler.handleDeleteSingleDocument - generic exception "
733
    		  + "when handling document: " + e.getMessage());
734
    }
735 1585 tao
    catch(Exception e)
736
    {
737 5014 daigle
      logMetacat.error("ReplicationHandler.handleDeleteSingleDocument - " + ReplicationService.METACAT_REPL_ERROR_MSG);
738
      logReplication.error("ReplicationHandler.handleDeleteSingleDocument - Failed to delete doc " + docId +
739 2663 sgarg
                                 " in db because because " + e.getMessage());
740 5014 daigle
      throw new HandlerException("ReplicationHandler.handleDeleteSingleDocument - generic exception "
741
    		  + "when handling document: " + e.getMessage());
742 1585 tao
    }
743
    finally
744
    {
745
       //return DBConnection
746
       DBConnectionPool.returnDBConnection(dbConn, serialNumber);
747 1037 tao
    }//finally
748 5392 berkley
    logD1.info("replication.handleDeleteSingleDocument localId:" + docId);
749 1585 tao
  }
750 2286 tao
751 1585 tao
  /* Handle updateLastCheckTimForSingleServer*/
752 2286 tao
  private void updateLastCheckTimeForSingleServer(ReplicationServer repServer)
753 5014 daigle
                                                  throws HandlerException
754 590 berkley
  {
755 1585 tao
    String server = repServer.getServerName();
756 1217 tao
    DBConnection dbConn = null;
757
    int serialNumber = -1;
758
    PreparedStatement pstmt = null;
759 590 berkley
    try
760
    {
761 1585 tao
      // Get DBConnection from pool
762 1217 tao
      dbConn=DBConnectionPool.
763 1585 tao
             getDBConnection("ReplicationHandler.updateLastCheckTimeForServer");
764 1217 tao
      serialNumber=dbConn.getCheckOutSerialNumber();
765 2286 tao
766 5014 daigle
      logReplication.info("ReplicationHandler.updateLastCheckTimeForSingleServer - Try to update last_check for server: "+server);
767 1585 tao
      // Get time from remote server
768
      URL dateurl = new URL("https://" + server + "?server="+
769 4698 daigle
      MetacatUtil.getLocalReplicationServerName()+"&action=gettime");
770 5014 daigle
      String datexml = ReplicationService.getURLContent(dateurl);
771
      logReplication.info("ReplicationHandler.updateLastCheckTimeForSingleServer - datexml: "+datexml);
772 1585 tao
      if (datexml!=null && !datexml.equals(""))
773
      {
774
         String datestr = datexml.substring(11, datexml.indexOf('<', 11));
775
         StringBuffer sql = new StringBuffer();
776 1751 tao
         /*sql.append("update xml_replication set last_checked = to_date('");
777 1585 tao
         sql.append(datestr).append("', 'YY-MM-DD HH24:MI:SS') where ");
778 1751 tao
         sql.append("server like '").append(server).append("'");*/
779
         sql.append("update xml_replication set last_checked = ");
780 5319 jones
         sql.append(DatabaseService.getInstance().getDBAdapter().toDate(datestr, "MM/DD/YY HH24:MI:SS"));
781 1751 tao
         sql.append(" where server like '").append(server).append("'");
782 1585 tao
         pstmt = dbConn.prepareStatement(sql.toString());
783 2286 tao
784 1585 tao
         pstmt.executeUpdate();
785
         dbConn.commit();
786
         pstmt.close();
787 5014 daigle
         logReplication.info("ReplicationHandler.updateLastCheckTimeForSingleServer - last_checked updated to "+datestr+" on "
788 2663 sgarg
                                      + server);
789 1585 tao
      }//if
790
      else
791
      {
792 2286 tao
793 5014 daigle
         logReplication.info("ReplicationHandler.updateLastCheckTimeForSingleServer - Failed to update last_checked for server "  +
794 2286 tao
                                  server + " in db because couldn't get time "
795 2663 sgarg
                                  );
796 1585 tao
         throw new Exception("Couldn't get time for server "+ server);
797
      }
798 2286 tao
799
    }//try
800 1585 tao
    catch(Exception e)
801
    {
802 5014 daigle
      logMetacat.error("ReplicationHandler.updateLastCheckTimeForSingleServer - " + ReplicationService.METACAT_REPL_ERROR_MSG);
803
      logReplication.error("ReplicationHandler.updateLastCheckTimeForSingleServer - Failed to update last_checked for server " +
804
                                server + " in db because because " + e.getMessage());
805
      throw new HandlerException("ReplicationHandler.updateLastCheckTimeForSingleServer - "
806
    		  + "Error updating last checked time: " + e.getMessage());
807 1585 tao
    }
808
    finally
809
    {
810
       //return DBConnection
811
       DBConnectionPool.returnDBConnection(dbConn, serialNumber);
812
    }//finally
813
  }
814 6118 leinfelder
815
  	/**
816
	 * Handle replicate system metadata
817
	 *
818
	 * @param remoteserver
819
	 * @param guid
820
	 * @throws HandlerException
821
	 */
822
	private void handleSystemMetadata(String remoteserver, String guid)
823
		throws HandlerException {
824
		try {
825 2286 tao
826 6118 leinfelder
			// Try get the system metadata from remote server
827
			String sysMetaURLStr = "https://" + remoteserver + "?server="
828
					+ MetacatUtil.getLocalReplicationServerName()
829
					+ "&action=getsystemmetadata&guid=" + guid;
830
			sysMetaURLStr = MetacatUtil.replaceWhiteSpaceForURL(sysMetaURLStr);
831
			URL sysMetaUrl = new URL(sysMetaURLStr);
832
			logReplication.info("ReplicationHandler.handleSystemMetadata - Sending message: "
833
							+ sysMetaUrl.toString());
834
			String systemMetadataXML = ReplicationService.getURLContent(sysMetaUrl);
835 2286 tao
836 6118 leinfelder
			logReplication.info("ReplicationHandler.handleSystemMetadata - guid in repl: " + guid);
837 2286 tao
838 6118 leinfelder
			// process system metadata
839
			if (systemMetadataXML != null) {
840 6367 leinfelder
				SystemMetadata sysMeta = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class,
841 6118 leinfelder
								new ByteArrayInputStream(systemMetadataXML
842
										.getBytes("UTF-8")));
843
				// String guid = sysMeta.getIdentifier().getValue();
844
				if (!IdentifierManager.getInstance().identifierExists(guid)) {
845
					logReplication.debug("Creating system metadata for guid: " + guid);
846
					IdentifierManager.getInstance().createSystemMetadata(sysMeta);
847
				}
848
				IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
849
			}
850
851
			logReplication.info("ReplicationHandler.handleSystemMetadata - Successfully replicated system metadata for guid: "
852
							+ guid);
853
854
			String ip = getIpFromURL(sysMetaUrl);
855
			EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, guid, "systemMetadata");
856
857
		} catch (Exception e) {
858
			logMetacat.error("ReplicationHandler.handleSystemMetadata - "
859
					+ ReplicationService.METACAT_REPL_ERROR_MSG);
860
			logReplication
861
					.error("ReplicationHandler.handleSystemMetadata - Failed to write system metadata "
862
							+ guid + " into db because " + e.getMessage());
863
			throw new HandlerException(
864
					"ReplicationHandler.handleSystemMetadata - generic exception "
865
							+ "writing Replication: " + e.getMessage());
866
		}
867
868
	}
869
870 1585 tao
  /**
871
   * updates xml_catalog with entries from other servers.
872
   */
873
  private void updateCatalog()
874
  {
875 5014 daigle
    logReplication.info("ReplicationHandler.updateCatalog - Start of updateCatalog");
876 1585 tao
    // ReplicationServer object in server list
877
    ReplicationServer replServer = null;
878
    PreparedStatement pstmt = null;
879
    String server = null;
880 2286 tao
881
882 1585 tao
    // Go through each ReplicationServer object in sererlist
883
    for (int j=0; j<serverList.size(); j++)
884 2286 tao
    {
885 5014 daigle
      Vector<Vector<String>> remoteCatalog = new Vector<Vector<String>>();
886
      Vector<String> publicId = new Vector<String>();
887 1585 tao
      try
888
      {
889 1292 tao
        // Get ReplicationServer object from server list
890
        replServer = serverList.serverAt(j);
891
        // Get server name from the ReplicationServer object
892
        server = replServer.getServerName();
893
        // Try to get catalog
894 1011 tao
        URL u = new URL("https://" + server + "?server="+
895 4698 daigle
        MetacatUtil.getLocalReplicationServerName()+"&action=getcatalog");
896 5014 daigle
        logReplication.info("ReplicationHandler.updateCatalog - sending message " + u.toString());
897
        String catxml = ReplicationService.getURLContent(u);
898 2286 tao
899 1292 tao
        // Make sure there are not error, no empty string
900
        if (catxml.indexOf("error")!=-1 || catxml==null||catxml.equals(""))
901
        {
902 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
903 1292 tao
        }
904 5175 daigle
        logReplication.debug("ReplicationHandler.updateCatalog - catxml: " + catxml);
905 590 berkley
        CatalogMessageHandler cmh = new CatalogMessageHandler();
906
        XMLReader catparser = initParser(cmh);
907
        catparser.parse(new InputSource(new StringReader(catxml)));
908
        //parse the returned catalog xml and put it into a vector
909 1585 tao
        remoteCatalog = cmh.getCatalogVect();
910 2286 tao
911 5175 daigle
        // Make sure remoteCatalog is not empty
912 1292 tao
        if (remoteCatalog.isEmpty())
913
        {
914 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
915 1292 tao
        }
916 2286 tao
917 5014 daigle
        String localcatxml = ReplicationService.getCatalogXML();
918 2286 tao
919 1292 tao
        // Make sure local catalog is no empty
920
        if (localcatxml==null||localcatxml.equals(""))
921
        {
922 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
923 1292 tao
        }
924 2286 tao
925 590 berkley
        cmh = new CatalogMessageHandler();
926
        catparser = initParser(cmh);
927
        catparser.parse(new InputSource(new StringReader(localcatxml)));
928 5014 daigle
        Vector<Vector<String>> localCatalog = cmh.getCatalogVect();
929 2286 tao
930 590 berkley
        //now we have the catalog from the remote server and this local server
931
        //we now need to compare the two and merge the differences.
932
        //the comparison is base on the public_id fields which is the 4th
933
        //entry in each row vector.
934 5014 daigle
        publicId = new Vector<String>();
935 590 berkley
        for(int i=0; i<localCatalog.size(); i++)
936
        {
937 5014 daigle
          Vector<String> v = new Vector<String>(localCatalog.elementAt(i));
938
          logReplication.info("ReplicationHandler.updateCatalog - v1: " + v.toString());
939 590 berkley
          publicId.add(new String((String)v.elementAt(3)));
940
        }
941 1585 tao
      }//try
942
      catch (Exception e)
943
      {
944 5014 daigle
        logMetacat.error("ReplicationHandler.updateCatalog - " + ReplicationService.METACAT_REPL_ERROR_MSG);
945
        logReplication.error("ReplicationHandler.updateCatalog - Failed to update catalog for server "+
946 1585 tao
                                    server + " because " +e.getMessage());
947
      }//catch
948 2286 tao
949 1585 tao
      for(int i=0; i<remoteCatalog.size(); i++)
950
      {
951
         // DConnection
952
        DBConnection dbConn = null;
953
        // DBConnection checkout serial number
954
        int serialNumber = -1;
955
        try
956 590 berkley
        {
957 1585 tao
            dbConn=DBConnectionPool.
958
                  getDBConnection("ReplicationHandler.updateCatalog");
959
            serialNumber=dbConn.getCheckOutSerialNumber();
960 5014 daigle
            Vector<String> v = remoteCatalog.elementAt(i);
961 6099 leinfelder
            //logMetacat.debug("v2: " + v.toString());
962
            //logMetacat.debug("i: " + i);
963
            //logMetacat.debug("remoteCatalog.size(): " + remoteCatalog.size());
964
            //logMetacat.debug("publicID: " + publicId.toString());
965 5014 daigle
            logReplication.info
966
                              ("ReplicationHandler.updateCatalog - v.elementAt(3): " + (String)v.elementAt(3));
967 1585 tao
           if(!publicId.contains(v.elementAt(3)))
968
           { //so we don't have this public id in our local table so we need to
969
             //add it.
970 6099 leinfelder
             //logMetacat.debug("in if");
971 1585 tao
             StringBuffer sql = new StringBuffer();
972
             sql.append("insert into xml_catalog (entry_type, source_doctype, ");
973
             sql.append("target_doctype, public_id, system_id) values (?,?,?,");
974
             sql.append("?,?)");
975 6099 leinfelder
             //logMetacat.debug("sql: " + sql.toString());
976 1585 tao
             pstmt = dbConn.prepareStatement(sql.toString());
977
             pstmt.setString(1, (String)v.elementAt(0));
978
             pstmt.setString(2, (String)v.elementAt(1));
979
             pstmt.setString(3, (String)v.elementAt(2));
980
             pstmt.setString(4, (String)v.elementAt(3));
981
             pstmt.setString(5, (String)v.elementAt(4));
982
             pstmt.execute();
983
             pstmt.close();
984 5014 daigle
             logReplication.info("ReplicationHandler.updateCatalog - Success fully to insert new publicid "+
985 1585 tao
                               (String)v.elementAt(3) + " from server"+server);
986
           }
987 590 berkley
        }
988 1585 tao
        catch(Exception e)
989
        {
990 5014 daigle
           logMetacat.error("ReplicationHandler.updateCatalog - " + ReplicationService.METACAT_REPL_ERROR_MSG);
991
           logReplication.error("ReplicationHandler.updateCatalog - Failed to update catalog for server "+
992 1585 tao
                                    server + " because " +e.getMessage());
993
        }//catch
994
        finally
995
        {
996
           DBConnectionPool.returnDBConnection(dbConn, serialNumber);
997 5175 daigle
        }//finally
998 1585 tao
      }//for remote catalog
999
    }//for server list
1000 5014 daigle
    logReplication.info("End of updateCatalog");
1001 590 berkley
  }
1002 2286 tao
1003 590 berkley
  /**
1004 579 berkley
   * Method that returns true if docid has already been "deleted" from metacat.
1005 582 berkley
   * This method really implements a truth table for deleted documents
1006 590 berkley
   * The table is (a docid in one of the tables is represented by the X):
1007 582 berkley
   * xml_docs      xml_revs      deleted?
1008
   * ------------------------------------
1009
   *   X             X             FALSE
1010
   *   X             _             FALSE
1011
   *   _             X             TRUE
1012
   *   _             _             TRUE
1013 579 berkley
   */
1014 5014 daigle
  private static boolean alreadyDeleted(String docid) throws HandlerException
1015 579 berkley
  {
1016 1217 tao
    DBConnection dbConn = null;
1017
    int serialNumber = -1;
1018
    PreparedStatement pstmt = null;
1019 579 berkley
    try
1020
    {
1021 1217 tao
      dbConn=DBConnectionPool.
1022
                  getDBConnection("ReplicationHandler.alreadyDeleted");
1023
      serialNumber=dbConn.getCheckOutSerialNumber();
1024 582 berkley
      boolean xml_docs = false;
1025
      boolean xml_revs = false;
1026 2286 tao
1027 579 berkley
      StringBuffer sb = new StringBuffer();
1028 582 berkley
      sb.append("select docid from xml_revisions where docid like '");
1029 579 berkley
      sb.append(docid).append("'");
1030 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
1031 579 berkley
      pstmt.execute();
1032
      ResultSet rs = pstmt.getResultSet();
1033
      boolean tablehasrows = rs.next();
1034
      if(tablehasrows)
1035
      {
1036 582 berkley
        xml_revs = true;
1037
      }
1038 2286 tao
1039 582 berkley
      sb = new StringBuffer();
1040
      sb.append("select docid from xml_documents where docid like '");
1041
      sb.append(docid).append("'");
1042 667 berkley
      pstmt.close();
1043 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
1044
      //increase usage count
1045
      dbConn.increaseUsageCount(1);
1046 582 berkley
      pstmt.execute();
1047
      rs = pstmt.getResultSet();
1048
      tablehasrows = rs.next();
1049 667 berkley
      pstmt.close();
1050 582 berkley
      if(tablehasrows)
1051
      {
1052
        xml_docs = true;
1053
      }
1054 2286 tao
1055 582 berkley
      if(xml_docs && xml_revs)
1056
      {
1057
        return false;
1058
      }
1059
      else if(xml_docs && !xml_revs)
1060
      {
1061
        return false;
1062
      }
1063
      else if(!xml_docs && xml_revs)
1064
      {
1065 579 berkley
        return true;
1066
      }
1067 582 berkley
      else if(!xml_docs && !xml_revs)
1068
      {
1069
        return true;
1070
      }
1071 579 berkley
    }
1072
    catch(Exception e)
1073
    {
1074 5014 daigle
      logMetacat.error("ReplicationHandler.alreadyDeleted - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1075
      logReplication.error("ReplicationHandler.alreadyDeleted - general error in alreadyDeleted: " +
1076 2663 sgarg
                          e.getMessage());
1077 5014 daigle
      throw new HandlerException("ReplicationHandler.alreadyDeleted - general error: "
1078
    		  + e.getMessage());
1079 579 berkley
    }
1080 667 berkley
    finally
1081
    {
1082 1217 tao
      try
1083
      {
1084
        pstmt.close();
1085
      }//try
1086
      catch (SQLException ee)
1087
      {
1088 5014 daigle
    	logMetacat.error("ReplicationHandler.alreadyDeleted - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1089
        logReplication.error("ReplicationHandler.alreadyDeleted - Error in replicationHandler.alreadyDeleted "+
1090 2663 sgarg
                          "to close pstmt: "+ee.getMessage());
1091 5014 daigle
        throw new HandlerException("ReplicationHandler.alreadyDeleted - SQL error when closing prepared statement: "
1092
      		  + ee.getMessage());
1093 1217 tao
      }//catch
1094
      finally
1095
      {
1096
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1097
      }//finally
1098
    }//finally
1099 579 berkley
    return false;
1100
  }
1101 533 berkley
1102 2286 tao
1103 533 berkley
  /**
1104 574 berkley
   * Method to initialize the message parser
1105
   */
1106
  public static XMLReader initParser(DefaultHandler dh)
1107 5014 daigle
          throws HandlerException
1108 574 berkley
  {
1109
    XMLReader parser = null;
1110
1111
    try {
1112
      ContentHandler chandler = dh;
1113
1114
      // Get an instance of the parser
1115 4213 daigle
      String parserName = PropertyService.getProperty("xml.saxparser");
1116 574 berkley
      parser = XMLReaderFactory.createXMLReader(parserName);
1117
1118
      // Turn off validation
1119
      parser.setFeature("http://xml.org/sax/features/validation", false);
1120 2286 tao
1121 574 berkley
      parser.setContentHandler((ContentHandler)chandler);
1122
      parser.setErrorHandler((ErrorHandler)chandler);
1123
1124 5014 daigle
    } catch (SAXException se) {
1125
      throw new HandlerException("ReplicationHandler.initParser - Sax error when "
1126
    		  + " initializing parser: " + se.getMessage());
1127
    } catch (PropertyNotFoundException pnfe) {
1128
        throw new HandlerException("ReplicationHandler.initParser - Property error when "
1129
      		  + " getting parser name: " + pnfe.getMessage());
1130
    }
1131 574 berkley
1132
    return parser;
1133
  }
1134 2286 tao
1135 2555 tao
  /**
1136 5175 daigle
	 * This method will combine given time string(in short format) to current
1137 5014 daigle
	 * date. If the given time (e.g 10:00 AM) passed the current time (e.g 2:00
1138
	 * PM Aug 21, 2005), then the time will set to second day, 10:00 AM Aug 22,
1139
	 * 2005. If the given time (e.g 10:00 AM) haven't passed the current time
1140
	 * (e.g 8:00 AM Aug 21, 2005) The time will set to be 10:00 AM Aug 21, 2005.
1141
	 *
1142
	 * @param givenTime
1143
	 *            the format should be "10:00 AM " or "2:00 PM"
1144
	 * @return
1145
	 * @throws Exception
1146
	 */
1147
	public static Date combinateCurrentDateAndGivenTime(String givenTime) throws HandlerException
1148 2555 tao
  {
1149 5014 daigle
	  try {
1150 2555 tao
     Date givenDate = parseTime(givenTime);
1151
     Date newDate = null;
1152
     Date now = new Date();
1153
     String currentTimeString = getTimeString(now);
1154
     Date currentTime = parseTime(currentTimeString);
1155
     if ( currentTime.getTime() >= givenDate.getTime())
1156
     {
1157 5014 daigle
        logReplication.info("ReplicationHandler.combinateCurrentDateAndGivenTime - Today already pass the given time, we should set it as tomorrow");
1158 2555 tao
        String dateAndTime = getDateString(now) + " " + givenTime;
1159
        Date combinationDate = parseDateTime(dateAndTime);
1160
        // new date should plus 24 hours to make is the second day
1161
        newDate = new Date(combinationDate.getTime()+24*3600*1000);
1162
     }
1163
     else
1164
     {
1165 5014 daigle
         logReplication.info("ReplicationHandler.combinateCurrentDateAndGivenTime - Today haven't pass the given time, we should it as today");
1166 2555 tao
         String dateAndTime = getDateString(now) + " " + givenTime;
1167
         newDate = parseDateTime(dateAndTime);
1168
     }
1169 5014 daigle
     logReplication.warn("ReplicationHandler.combinateCurrentDateAndGivenTime - final setting time is "+ newDate.toString());
1170 2555 tao
     return newDate;
1171 5014 daigle
	  } catch (ParseException pe) {
1172
		  throw new HandlerException("ReplicationHandler.combinateCurrentDateAndGivenTime - "
1173
				  + "parsing error: "  + pe.getMessage());
1174
	  }
1175 2555 tao
  }
1176 2286 tao
1177 2555 tao
  /*
1178 5014 daigle
	 * parse a given string to Time in short format. For example, given time is
1179
	 * 10:00 AM, the date will be return as Jan 1 1970, 10:00 AM
1180
	 */
1181
  private static Date parseTime(String timeString) throws ParseException
1182 2555 tao
  {
1183
    DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
1184
    Date time = format.parse(timeString);
1185 5014 daigle
    logReplication.info("ReplicationHandler.parseTime - Date string is after parse a time string "
1186 2663 sgarg
                              +time.toString());
1187 2555 tao
    return time;
1188
1189
  }
1190
1191
  /*
1192 5175 daigle
   * Parse a given string to date and time. Date format is long and time
1193 2555 tao
   * format is short.
1194
   */
1195 5014 daigle
  private static Date parseDateTime(String timeString) throws ParseException
1196 2555 tao
  {
1197
    DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT);
1198
    Date time = format.parse(timeString);
1199 5014 daigle
    logReplication.info("ReplicationHandler.parseDateTime - Date string is after parse a time string "+
1200 2663 sgarg
                             time.toString());
1201 2555 tao
    return time;
1202
  }
1203
1204
  /*
1205
   * Get a date string from a Date object. The date format will be long
1206
   */
1207
  private static String getDateString(Date now)
1208
  {
1209
     DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
1210
     String s = df.format(now);
1211 5014 daigle
     logReplication.info("ReplicationHandler.getDateString - Today is " + s);
1212 2555 tao
     return s;
1213
  }
1214
1215
  /*
1216
   * Get a time string from a Date object, the time format will be short
1217
   */
1218
  private static String getTimeString(Date now)
1219
  {
1220
     DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
1221
     String s = df.format(now);
1222 5014 daigle
     logReplication.info("ReplicationHandler.getTimeString - Time is " + s);
1223 2555 tao
     return s;
1224
  }
1225 2608 tao
1226
1227
  /*
1228 4080 daigle
	 * This method will go through the docid list both in xml_Documents table
1229
	 * and in xml_revisions table @author tao
1230
	 */
1231 5014 daigle
	private void handleDocList(Vector<Vector<String>> docList, String tableName) {
1232 4080 daigle
		boolean dataFile = false;
1233
		for (int j = 0; j < docList.size(); j++) {
1234
			// initial dataFile is false
1235
			dataFile = false;
1236
			// w is information for one document, information contain
1237
			// docid, rev, server or datafile.
1238 5014 daigle
			Vector<String> w = new Vector<String>(docList.elementAt(j));
1239 4080 daigle
			// Check if the vector w contain "datafile"
1240
			// If it has, this document is data file
1241
			try {
1242 4173 daigle
				if (w.contains((String) PropertyService.getProperty("replication.datafileflag"))) {
1243 4080 daigle
					dataFile = true;
1244
				}
1245
			} catch (PropertyNotFoundException pnfe) {
1246 5014 daigle
				logMetacat.error("ReplicationHandler.handleDocList - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1247
				logReplication.error("ReplicationHandler.handleDocList - Could not retrieve data file flag property.  "
1248 4080 daigle
						+ "Leaving as false: " + pnfe.getMessage());
1249
			}
1250 6099 leinfelder
			// logMetacat.debug("w: " + w.toString());
1251 4080 daigle
			// Get docid
1252
			String docid = (String) w.elementAt(0);
1253 5014 daigle
			logReplication.info("docid: " + docid);
1254 4080 daigle
			// Get revision number
1255
			int rev = Integer.parseInt((String) w.elementAt(1));
1256 5014 daigle
			logReplication.info("rev: " + rev);
1257 5175 daigle
			// Get remote server name (it is may not be doc home server because
1258 4080 daigle
			// the new hub feature
1259
			String remoteServer = (String) w.elementAt(2);
1260
			remoteServer = remoteServer.trim();
1261 2608 tao
1262 4080 daigle
			try {
1263
				if (tableName.equals(DocumentImpl.DOCUMENTTABLE)) {
1264
					handleDocInXMLDocuments(docid, rev, remoteServer, dataFile);
1265
				} else if (tableName.equals(DocumentImpl.REVISIONTABLE)) {
1266
					handleDocInXMLRevisions(docid, rev, remoteServer, dataFile);
1267
				} else {
1268
					continue;
1269
				}
1270 2608 tao
1271 4861 daigle
			} catch (Exception e) {
1272 5014 daigle
				logMetacat.error("ReplicationHandler.handleDocList - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1273
				logReplication.error("ReplicationHandler.handleDocList - error to handle update doc in " + tableName
1274 4861 daigle
						+ " in time replication" + e.getMessage());
1275 4080 daigle
				continue;
1276
			}
1277 5175 daigle
1278
	        if (_xmlDocQueryCount > 0 && (_xmlDocQueryCount % 100) == 0) {
1279
	        	logMetacat.debug("ReplicationHandler.update - xml_doc query count: " + _xmlDocQueryCount +
1280
	        			", xml_doc avg query time: " + (_xmlDocQueryTime / _xmlDocQueryCount));
1281
	        }
1282
1283
	        if (_xmlRevQueryCount > 0 && (_xmlRevQueryCount % 100) == 0) {
1284
	        	logMetacat.debug("ReplicationHandler.update - xml_rev query count: " + _xmlRevQueryCount +
1285
	        			", xml_rev avg query time: " + (_xmlRevQueryTime / _xmlRevQueryCount));
1286
	        }
1287 4080 daigle
1288
		}// for update docs
1289
1290
	}
1291 2608 tao
1292
   /*
1293 4080 daigle
	 * This method will handle doc in xml_documents table.
1294
	 */
1295 2608 tao
   private void handleDocInXMLDocuments(String docid, int rev, String remoteServer, boolean dataFile)
1296 5014 daigle
                                        throws HandlerException
1297 2608 tao
   {
1298
       // compare the update rev and local rev to see what need happen
1299
       int localrev = -1;
1300
       String action = null;
1301
       boolean flag = false;
1302
       try
1303
       {
1304 5175 daigle
    	 long docQueryStartTime = System.currentTimeMillis();
1305 2641 tao
         localrev = DBUtil.getLatestRevisionInDocumentTable(docid);
1306 5175 daigle
         long docQueryEndTime = System.currentTimeMillis();
1307
         _xmlDocQueryTime += (docQueryEndTime - docQueryStartTime);
1308
         _xmlDocQueryCount++;
1309 2608 tao
       }
1310
       catch (SQLException e)
1311
       {
1312 5014 daigle
    	 logMetacat.error("ReplicationHandler.handleDocInXMLDocuments - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1313
         logReplication.error("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " could not "+
1314 2663 sgarg
                                " be found because " + e.getMessage());
1315 5014 daigle
         logReplication.error("ReplicationHandler.handleDocInXMLDocuments - " + DOCERRORNUMBER+"Docid "+ docid + " could not be "+
1316 2608 tao
                 "written because error happend to find it's local revision");
1317 2739 tao
         DOCERRORNUMBER++;
1318 5014 daigle
         throw new HandlerException ("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " could not "+
1319
                 " be found: " + e.getMessage());
1320 2608 tao
       }
1321 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " is "+
1322 2663 sgarg
                               localrev);
1323 2608 tao
1324
       //check the revs for an update because this document is in the
1325
       //local DB, it might be out of date.
1326
       if (localrev == -1)
1327
       {
1328 2713 tao
          // check if the revision is in the revision table
1329 5014 daigle
    	   Vector<Integer> localRevVector = null;
1330
    	 try {
1331 5175 daigle
        	 long revQueryStartTime = System.currentTimeMillis();
1332 5014 daigle
    		 localRevVector = DBUtil.getRevListFromRevisionTable(docid);
1333 5175 daigle
             long revQueryEndTime = System.currentTimeMillis();
1334
             _xmlRevQueryTime += (revQueryEndTime - revQueryStartTime);
1335
             _xmlRevQueryCount++;
1336 5014 daigle
    	 } catch (SQLException sqle) {
1337
    		 throw new HandlerException("ReplicationHandler.handleDocInXMLDocuments - SQL error "
1338
    				 + " when getting rev list for docid: " + docid + " : " + sqle.getMessage());
1339
    	 }
1340 2713 tao
         if (localRevVector != null && localRevVector.contains(new Integer(rev)))
1341
         {
1342
             // this version was deleted, so don't need replicate
1343
             flag = false;
1344
         }
1345
         else
1346
         {
1347
           //insert this document as new because it is not in the local DB
1348
           action = "INSERT";
1349
           flag = true;
1350
         }
1351 2608 tao
       }
1352
       else
1353
       {
1354
         if(localrev == rev)
1355
         {
1356
           // Local meatacat has the same rev to remote host, don't need
1357
           // update and flag set false
1358
           flag = false;
1359
         }
1360
         else if(localrev < rev)
1361
         {
1362
           //this document needs to be updated so send an read request
1363
           action = "UPDATE";
1364
           flag = true;
1365
         }
1366
       }
1367 2641 tao
1368 5014 daigle
       String accNumber = null;
1369
       try {
1370
    	   accNumber = docid + PropertyService.getProperty("document.accNumSeparator") + rev;
1371
       } catch (PropertyNotFoundException pnfe) {
1372
    	   throw new HandlerException("ReplicationHandler.handleDocInXMLDocuments - error getting "
1373
    			   + "account number separator : " + pnfe.getMessage());
1374
       }
1375 2608 tao
       // this is non-data file
1376
       if(flag && !dataFile)
1377
       {
1378
         try
1379
         {
1380 2641 tao
           handleSingleXMLDocument(remoteServer, action, accNumber, DocumentImpl.DOCUMENTTABLE);
1381 2608 tao
         }
1382 5014 daigle
         catch(HandlerException he)
1383 2608 tao
         {
1384
           // skip this document
1385 5014 daigle
           throw he;
1386 2608 tao
         }
1387
       }//if for non-data file
1388
1389
        // this is for data file
1390
       if(flag && dataFile)
1391
       {
1392
         try
1393
         {
1394 2641 tao
           handleSingleDataFile(remoteServer, action, accNumber, DocumentImpl.DOCUMENTTABLE);
1395 2608 tao
         }
1396 5014 daigle
         catch(HandlerException he)
1397 2608 tao
         {
1398 5175 daigle
           // skip this data file
1399 5014 daigle
           throw he;
1400 2608 tao
         }
1401
1402 5175 daigle
       }//for data file
1403 2608 tao
   }
1404
1405
   /*
1406
    * This method will handle doc in xml_documents table.
1407
    */
1408
   private void handleDocInXMLRevisions(String docid, int rev, String remoteServer, boolean dataFile)
1409 5014 daigle
                                        throws HandlerException
1410 2608 tao
   {
1411
       // compare the update rev and local rev to see what need happen
1412 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - In handle repliation revsion table");
1413
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - the docid is "+ docid);
1414
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - The rev is "+rev);
1415
       Vector<Integer> localrev = null;
1416 2608 tao
       String action = "INSERT";
1417
       boolean flag = false;
1418
       try
1419
       {
1420 5175 daigle
      	 long revQueryStartTime = System.currentTimeMillis();
1421 2608 tao
         localrev = DBUtil.getRevListFromRevisionTable(docid);
1422 5175 daigle
         long revQueryEndTime = System.currentTimeMillis();
1423
         _xmlRevQueryTime += (revQueryEndTime - revQueryStartTime);
1424
         _xmlRevQueryCount++;
1425 2608 tao
       }
1426 5014 daigle
       catch (SQLException sqle)
1427 2608 tao
       {
1428 5014 daigle
    	 logMetacat.error("ReplicationHandler.handleDocInXMLDocuments - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1429
         logReplication.error("ReplicationHandler.handleDocInXMLRevisions - Local rev for docid "+ docid + " could not "+
1430
                                " be found because " + sqle.getMessage());
1431 2739 tao
         REVERRORNUMBER++;
1432 5014 daigle
         throw new HandlerException ("ReplicationHandler.handleDocInXMLRevisions - SQL exception getting rev list: "
1433
        		 + sqle.getMessage());
1434 2608 tao
       }
1435 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - rev list in xml_revision table for docid "+ docid + " is "+
1436 2663 sgarg
                               localrev.toString());
1437 2608 tao
1438
       // if the rev is not in the xml_revision, we need insert it
1439
       if (!localrev.contains(new Integer(rev)))
1440
       {
1441
           flag = true;
1442
       }
1443 2641 tao
1444 5014 daigle
       String accNumber = null;
1445
       try {
1446
    	   accNumber = docid + PropertyService.getProperty("document.accNumSeparator") + rev;
1447
       } catch (PropertyNotFoundException pnfe) {
1448
    	   throw new HandlerException("ReplicationHandler.handleDocInXMLRevisions - error getting "
1449
    			   + "account number separator : " + pnfe.getMessage());
1450
       }
1451 2608 tao
       // this is non-data file
1452
       if(flag && !dataFile)
1453
       {
1454
         try
1455
         {
1456 2641 tao
1457
           handleSingleXMLDocument(remoteServer, action, accNumber, DocumentImpl.REVISIONTABLE);
1458 2608 tao
         }
1459 5014 daigle
         catch(HandlerException he)
1460 2608 tao
         {
1461
           // skip this document
1462 5014 daigle
           throw he;
1463 2608 tao
         }
1464
       }//if for non-data file
1465
1466
        // this is for data file
1467
       if(flag && dataFile)
1468
       {
1469
         try
1470
         {
1471 2641 tao
           handleSingleDataFile(remoteServer, action, accNumber, DocumentImpl.REVISIONTABLE);
1472 2608 tao
         }
1473 5014 daigle
         catch(HandlerException he)
1474 2608 tao
         {
1475 5175 daigle
           // skip this data file
1476 5014 daigle
           throw he;
1477 2608 tao
         }
1478
1479 5175 daigle
       }//for data file
1480 2608 tao
   }
1481 3234 tao
1482
   /*
1483
    * Return a ip address for given url
1484
    */
1485
   private String getIpFromURL(URL url)
1486
   {
1487
	   String ip = null;
1488
	   try
1489
	   {
1490
	      InetAddress address = InetAddress.getByName(url.getHost());
1491
	      ip = address.getHostAddress();
1492
	   }
1493
	   catch(UnknownHostException e)
1494
	   {
1495 5014 daigle
		   logMetacat.error("ReplicationHandler.getIpFromURL - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1496
		   logReplication.error("ReplicationHandler.getIpFromURL - Error in get ip address for host: "
1497 3234 tao
                   +e.getMessage());
1498
	   }
1499
1500
	   return ip;
1501
   }
1502 2608 tao
1503 522 berkley
}