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 6102 leinfelder
import org.dataone.service.types.util.ServiceTypeUtil;
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
    		  (SystemMetadata) ServiceTypeUtil.deserializeServiceType(
446
    				  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
      		  (SystemMetadata) ServiceTypeUtil.deserializeServiceType(
605
      				  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
				SystemMetadata sysMeta = (SystemMetadata) ServiceTypeUtil
841
						.deserializeServiceType(SystemMetadata.class,
842
								new ByteArrayInputStream(systemMetadataXML
843
										.getBytes("UTF-8")));
844
				// String guid = sysMeta.getIdentifier().getValue();
845
				if (!IdentifierManager.getInstance().identifierExists(guid)) {
846
					logReplication.debug("Creating system metadata for guid: " + guid);
847
					IdentifierManager.getInstance().createSystemMetadata(sysMeta);
848
				}
849
				IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
850
			}
851
852
			logReplication.info("ReplicationHandler.handleSystemMetadata - Successfully replicated system metadata for guid: "
853
							+ guid);
854
855
			String ip = getIpFromURL(sysMetaUrl);
856
			EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, guid, "systemMetadata");
857
858
		} catch (Exception e) {
859
			logMetacat.error("ReplicationHandler.handleSystemMetadata - "
860
					+ ReplicationService.METACAT_REPL_ERROR_MSG);
861
			logReplication
862
					.error("ReplicationHandler.handleSystemMetadata - Failed to write system metadata "
863
							+ guid + " into db because " + e.getMessage());
864
			throw new HandlerException(
865
					"ReplicationHandler.handleSystemMetadata - generic exception "
866
							+ "writing Replication: " + e.getMessage());
867
		}
868
869
	}
870
871 1585 tao
  /**
872
   * updates xml_catalog with entries from other servers.
873
   */
874
  private void updateCatalog()
875
  {
876 5014 daigle
    logReplication.info("ReplicationHandler.updateCatalog - Start of updateCatalog");
877 1585 tao
    // ReplicationServer object in server list
878
    ReplicationServer replServer = null;
879
    PreparedStatement pstmt = null;
880
    String server = null;
881 2286 tao
882
883 1585 tao
    // Go through each ReplicationServer object in sererlist
884
    for (int j=0; j<serverList.size(); j++)
885 2286 tao
    {
886 5014 daigle
      Vector<Vector<String>> remoteCatalog = new Vector<Vector<String>>();
887
      Vector<String> publicId = new Vector<String>();
888 1585 tao
      try
889
      {
890 1292 tao
        // Get ReplicationServer object from server list
891
        replServer = serverList.serverAt(j);
892
        // Get server name from the ReplicationServer object
893
        server = replServer.getServerName();
894
        // Try to get catalog
895 1011 tao
        URL u = new URL("https://" + server + "?server="+
896 4698 daigle
        MetacatUtil.getLocalReplicationServerName()+"&action=getcatalog");
897 5014 daigle
        logReplication.info("ReplicationHandler.updateCatalog - sending message " + u.toString());
898
        String catxml = ReplicationService.getURLContent(u);
899 2286 tao
900 1292 tao
        // Make sure there are not error, no empty string
901
        if (catxml.indexOf("error")!=-1 || catxml==null||catxml.equals(""))
902
        {
903 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
904 1292 tao
        }
905 5175 daigle
        logReplication.debug("ReplicationHandler.updateCatalog - catxml: " + catxml);
906 590 berkley
        CatalogMessageHandler cmh = new CatalogMessageHandler();
907
        XMLReader catparser = initParser(cmh);
908
        catparser.parse(new InputSource(new StringReader(catxml)));
909
        //parse the returned catalog xml and put it into a vector
910 1585 tao
        remoteCatalog = cmh.getCatalogVect();
911 2286 tao
912 5175 daigle
        // Make sure remoteCatalog is not empty
913 1292 tao
        if (remoteCatalog.isEmpty())
914
        {
915 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
916 1292 tao
        }
917 2286 tao
918 5014 daigle
        String localcatxml = ReplicationService.getCatalogXML();
919 2286 tao
920 1292 tao
        // Make sure local catalog is no empty
921
        if (localcatxml==null||localcatxml.equals(""))
922
        {
923 1585 tao
          throw new Exception("Couldn't get catalog list form server " +server);
924 1292 tao
        }
925 2286 tao
926 590 berkley
        cmh = new CatalogMessageHandler();
927
        catparser = initParser(cmh);
928
        catparser.parse(new InputSource(new StringReader(localcatxml)));
929 5014 daigle
        Vector<Vector<String>> localCatalog = cmh.getCatalogVect();
930 2286 tao
931 590 berkley
        //now we have the catalog from the remote server and this local server
932
        //we now need to compare the two and merge the differences.
933
        //the comparison is base on the public_id fields which is the 4th
934
        //entry in each row vector.
935 5014 daigle
        publicId = new Vector<String>();
936 590 berkley
        for(int i=0; i<localCatalog.size(); i++)
937
        {
938 5014 daigle
          Vector<String> v = new Vector<String>(localCatalog.elementAt(i));
939
          logReplication.info("ReplicationHandler.updateCatalog - v1: " + v.toString());
940 590 berkley
          publicId.add(new String((String)v.elementAt(3)));
941
        }
942 1585 tao
      }//try
943
      catch (Exception e)
944
      {
945 5014 daigle
        logMetacat.error("ReplicationHandler.updateCatalog - " + ReplicationService.METACAT_REPL_ERROR_MSG);
946
        logReplication.error("ReplicationHandler.updateCatalog - Failed to update catalog for server "+
947 1585 tao
                                    server + " because " +e.getMessage());
948
      }//catch
949 2286 tao
950 1585 tao
      for(int i=0; i<remoteCatalog.size(); i++)
951
      {
952
         // DConnection
953
        DBConnection dbConn = null;
954
        // DBConnection checkout serial number
955
        int serialNumber = -1;
956
        try
957 590 berkley
        {
958 1585 tao
            dbConn=DBConnectionPool.
959
                  getDBConnection("ReplicationHandler.updateCatalog");
960
            serialNumber=dbConn.getCheckOutSerialNumber();
961 5014 daigle
            Vector<String> v = remoteCatalog.elementAt(i);
962 6099 leinfelder
            //logMetacat.debug("v2: " + v.toString());
963
            //logMetacat.debug("i: " + i);
964
            //logMetacat.debug("remoteCatalog.size(): " + remoteCatalog.size());
965
            //logMetacat.debug("publicID: " + publicId.toString());
966 5014 daigle
            logReplication.info
967
                              ("ReplicationHandler.updateCatalog - v.elementAt(3): " + (String)v.elementAt(3));
968 1585 tao
           if(!publicId.contains(v.elementAt(3)))
969
           { //so we don't have this public id in our local table so we need to
970
             //add it.
971 6099 leinfelder
             //logMetacat.debug("in if");
972 1585 tao
             StringBuffer sql = new StringBuffer();
973
             sql.append("insert into xml_catalog (entry_type, source_doctype, ");
974
             sql.append("target_doctype, public_id, system_id) values (?,?,?,");
975
             sql.append("?,?)");
976 6099 leinfelder
             //logMetacat.debug("sql: " + sql.toString());
977 1585 tao
             pstmt = dbConn.prepareStatement(sql.toString());
978
             pstmt.setString(1, (String)v.elementAt(0));
979
             pstmt.setString(2, (String)v.elementAt(1));
980
             pstmt.setString(3, (String)v.elementAt(2));
981
             pstmt.setString(4, (String)v.elementAt(3));
982
             pstmt.setString(5, (String)v.elementAt(4));
983
             pstmt.execute();
984
             pstmt.close();
985 5014 daigle
             logReplication.info("ReplicationHandler.updateCatalog - Success fully to insert new publicid "+
986 1585 tao
                               (String)v.elementAt(3) + " from server"+server);
987
           }
988 590 berkley
        }
989 1585 tao
        catch(Exception e)
990
        {
991 5014 daigle
           logMetacat.error("ReplicationHandler.updateCatalog - " + ReplicationService.METACAT_REPL_ERROR_MSG);
992
           logReplication.error("ReplicationHandler.updateCatalog - Failed to update catalog for server "+
993 1585 tao
                                    server + " because " +e.getMessage());
994
        }//catch
995
        finally
996
        {
997
           DBConnectionPool.returnDBConnection(dbConn, serialNumber);
998 5175 daigle
        }//finally
999 1585 tao
      }//for remote catalog
1000
    }//for server list
1001 5014 daigle
    logReplication.info("End of updateCatalog");
1002 590 berkley
  }
1003 2286 tao
1004 590 berkley
  /**
1005 579 berkley
   * Method that returns true if docid has already been "deleted" from metacat.
1006 582 berkley
   * This method really implements a truth table for deleted documents
1007 590 berkley
   * The table is (a docid in one of the tables is represented by the X):
1008 582 berkley
   * xml_docs      xml_revs      deleted?
1009
   * ------------------------------------
1010
   *   X             X             FALSE
1011
   *   X             _             FALSE
1012
   *   _             X             TRUE
1013
   *   _             _             TRUE
1014 579 berkley
   */
1015 5014 daigle
  private static boolean alreadyDeleted(String docid) throws HandlerException
1016 579 berkley
  {
1017 1217 tao
    DBConnection dbConn = null;
1018
    int serialNumber = -1;
1019
    PreparedStatement pstmt = null;
1020 579 berkley
    try
1021
    {
1022 1217 tao
      dbConn=DBConnectionPool.
1023
                  getDBConnection("ReplicationHandler.alreadyDeleted");
1024
      serialNumber=dbConn.getCheckOutSerialNumber();
1025 582 berkley
      boolean xml_docs = false;
1026
      boolean xml_revs = false;
1027 2286 tao
1028 579 berkley
      StringBuffer sb = new StringBuffer();
1029 582 berkley
      sb.append("select docid from xml_revisions where docid like '");
1030 579 berkley
      sb.append(docid).append("'");
1031 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
1032 579 berkley
      pstmt.execute();
1033
      ResultSet rs = pstmt.getResultSet();
1034
      boolean tablehasrows = rs.next();
1035
      if(tablehasrows)
1036
      {
1037 582 berkley
        xml_revs = true;
1038
      }
1039 2286 tao
1040 582 berkley
      sb = new StringBuffer();
1041
      sb.append("select docid from xml_documents where docid like '");
1042
      sb.append(docid).append("'");
1043 667 berkley
      pstmt.close();
1044 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
1045
      //increase usage count
1046
      dbConn.increaseUsageCount(1);
1047 582 berkley
      pstmt.execute();
1048
      rs = pstmt.getResultSet();
1049
      tablehasrows = rs.next();
1050 667 berkley
      pstmt.close();
1051 582 berkley
      if(tablehasrows)
1052
      {
1053
        xml_docs = true;
1054
      }
1055 2286 tao
1056 582 berkley
      if(xml_docs && xml_revs)
1057
      {
1058
        return false;
1059
      }
1060
      else if(xml_docs && !xml_revs)
1061
      {
1062
        return false;
1063
      }
1064
      else if(!xml_docs && xml_revs)
1065
      {
1066 579 berkley
        return true;
1067
      }
1068 582 berkley
      else if(!xml_docs && !xml_revs)
1069
      {
1070
        return true;
1071
      }
1072 579 berkley
    }
1073
    catch(Exception e)
1074
    {
1075 5014 daigle
      logMetacat.error("ReplicationHandler.alreadyDeleted - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1076
      logReplication.error("ReplicationHandler.alreadyDeleted - general error in alreadyDeleted: " +
1077 2663 sgarg
                          e.getMessage());
1078 5014 daigle
      throw new HandlerException("ReplicationHandler.alreadyDeleted - general error: "
1079
    		  + e.getMessage());
1080 579 berkley
    }
1081 667 berkley
    finally
1082
    {
1083 1217 tao
      try
1084
      {
1085
        pstmt.close();
1086
      }//try
1087
      catch (SQLException ee)
1088
      {
1089 5014 daigle
    	logMetacat.error("ReplicationHandler.alreadyDeleted - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1090
        logReplication.error("ReplicationHandler.alreadyDeleted - Error in replicationHandler.alreadyDeleted "+
1091 2663 sgarg
                          "to close pstmt: "+ee.getMessage());
1092 5014 daigle
        throw new HandlerException("ReplicationHandler.alreadyDeleted - SQL error when closing prepared statement: "
1093
      		  + ee.getMessage());
1094 1217 tao
      }//catch
1095
      finally
1096
      {
1097
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1098
      }//finally
1099
    }//finally
1100 579 berkley
    return false;
1101
  }
1102 533 berkley
1103 2286 tao
1104 533 berkley
  /**
1105 574 berkley
   * Method to initialize the message parser
1106
   */
1107
  public static XMLReader initParser(DefaultHandler dh)
1108 5014 daigle
          throws HandlerException
1109 574 berkley
  {
1110
    XMLReader parser = null;
1111
1112
    try {
1113
      ContentHandler chandler = dh;
1114
1115
      // Get an instance of the parser
1116 4213 daigle
      String parserName = PropertyService.getProperty("xml.saxparser");
1117 574 berkley
      parser = XMLReaderFactory.createXMLReader(parserName);
1118
1119
      // Turn off validation
1120
      parser.setFeature("http://xml.org/sax/features/validation", false);
1121 2286 tao
1122 574 berkley
      parser.setContentHandler((ContentHandler)chandler);
1123
      parser.setErrorHandler((ErrorHandler)chandler);
1124
1125 5014 daigle
    } catch (SAXException se) {
1126
      throw new HandlerException("ReplicationHandler.initParser - Sax error when "
1127
    		  + " initializing parser: " + se.getMessage());
1128
    } catch (PropertyNotFoundException pnfe) {
1129
        throw new HandlerException("ReplicationHandler.initParser - Property error when "
1130
      		  + " getting parser name: " + pnfe.getMessage());
1131
    }
1132 574 berkley
1133
    return parser;
1134
  }
1135 2286 tao
1136 2555 tao
  /**
1137 5175 daigle
	 * This method will combine given time string(in short format) to current
1138 5014 daigle
	 * date. If the given time (e.g 10:00 AM) passed the current time (e.g 2:00
1139
	 * PM Aug 21, 2005), then the time will set to second day, 10:00 AM Aug 22,
1140
	 * 2005. If the given time (e.g 10:00 AM) haven't passed the current time
1141
	 * (e.g 8:00 AM Aug 21, 2005) The time will set to be 10:00 AM Aug 21, 2005.
1142
	 *
1143
	 * @param givenTime
1144
	 *            the format should be "10:00 AM " or "2:00 PM"
1145
	 * @return
1146
	 * @throws Exception
1147
	 */
1148
	public static Date combinateCurrentDateAndGivenTime(String givenTime) throws HandlerException
1149 2555 tao
  {
1150 5014 daigle
	  try {
1151 2555 tao
     Date givenDate = parseTime(givenTime);
1152
     Date newDate = null;
1153
     Date now = new Date();
1154
     String currentTimeString = getTimeString(now);
1155
     Date currentTime = parseTime(currentTimeString);
1156
     if ( currentTime.getTime() >= givenDate.getTime())
1157
     {
1158 5014 daigle
        logReplication.info("ReplicationHandler.combinateCurrentDateAndGivenTime - Today already pass the given time, we should set it as tomorrow");
1159 2555 tao
        String dateAndTime = getDateString(now) + " " + givenTime;
1160
        Date combinationDate = parseDateTime(dateAndTime);
1161
        // new date should plus 24 hours to make is the second day
1162
        newDate = new Date(combinationDate.getTime()+24*3600*1000);
1163
     }
1164
     else
1165
     {
1166 5014 daigle
         logReplication.info("ReplicationHandler.combinateCurrentDateAndGivenTime - Today haven't pass the given time, we should it as today");
1167 2555 tao
         String dateAndTime = getDateString(now) + " " + givenTime;
1168
         newDate = parseDateTime(dateAndTime);
1169
     }
1170 5014 daigle
     logReplication.warn("ReplicationHandler.combinateCurrentDateAndGivenTime - final setting time is "+ newDate.toString());
1171 2555 tao
     return newDate;
1172 5014 daigle
	  } catch (ParseException pe) {
1173
		  throw new HandlerException("ReplicationHandler.combinateCurrentDateAndGivenTime - "
1174
				  + "parsing error: "  + pe.getMessage());
1175
	  }
1176 2555 tao
  }
1177 2286 tao
1178 2555 tao
  /*
1179 5014 daigle
	 * parse a given string to Time in short format. For example, given time is
1180
	 * 10:00 AM, the date will be return as Jan 1 1970, 10:00 AM
1181
	 */
1182
  private static Date parseTime(String timeString) throws ParseException
1183 2555 tao
  {
1184
    DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
1185
    Date time = format.parse(timeString);
1186 5014 daigle
    logReplication.info("ReplicationHandler.parseTime - Date string is after parse a time string "
1187 2663 sgarg
                              +time.toString());
1188 2555 tao
    return time;
1189
1190
  }
1191
1192
  /*
1193 5175 daigle
   * Parse a given string to date and time. Date format is long and time
1194 2555 tao
   * format is short.
1195
   */
1196 5014 daigle
  private static Date parseDateTime(String timeString) throws ParseException
1197 2555 tao
  {
1198
    DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT);
1199
    Date time = format.parse(timeString);
1200 5014 daigle
    logReplication.info("ReplicationHandler.parseDateTime - Date string is after parse a time string "+
1201 2663 sgarg
                             time.toString());
1202 2555 tao
    return time;
1203
  }
1204
1205
  /*
1206
   * Get a date string from a Date object. The date format will be long
1207
   */
1208
  private static String getDateString(Date now)
1209
  {
1210
     DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
1211
     String s = df.format(now);
1212 5014 daigle
     logReplication.info("ReplicationHandler.getDateString - Today is " + s);
1213 2555 tao
     return s;
1214
  }
1215
1216
  /*
1217
   * Get a time string from a Date object, the time format will be short
1218
   */
1219
  private static String getTimeString(Date now)
1220
  {
1221
     DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
1222
     String s = df.format(now);
1223 5014 daigle
     logReplication.info("ReplicationHandler.getTimeString - Time is " + s);
1224 2555 tao
     return s;
1225
  }
1226 2608 tao
1227
1228
  /*
1229 4080 daigle
	 * This method will go through the docid list both in xml_Documents table
1230
	 * and in xml_revisions table @author tao
1231
	 */
1232 5014 daigle
	private void handleDocList(Vector<Vector<String>> docList, String tableName) {
1233 4080 daigle
		boolean dataFile = false;
1234
		for (int j = 0; j < docList.size(); j++) {
1235
			// initial dataFile is false
1236
			dataFile = false;
1237
			// w is information for one document, information contain
1238
			// docid, rev, server or datafile.
1239 5014 daigle
			Vector<String> w = new Vector<String>(docList.elementAt(j));
1240 4080 daigle
			// Check if the vector w contain "datafile"
1241
			// If it has, this document is data file
1242
			try {
1243 4173 daigle
				if (w.contains((String) PropertyService.getProperty("replication.datafileflag"))) {
1244 4080 daigle
					dataFile = true;
1245
				}
1246
			} catch (PropertyNotFoundException pnfe) {
1247 5014 daigle
				logMetacat.error("ReplicationHandler.handleDocList - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1248
				logReplication.error("ReplicationHandler.handleDocList - Could not retrieve data file flag property.  "
1249 4080 daigle
						+ "Leaving as false: " + pnfe.getMessage());
1250
			}
1251 6099 leinfelder
			// logMetacat.debug("w: " + w.toString());
1252 4080 daigle
			// Get docid
1253
			String docid = (String) w.elementAt(0);
1254 5014 daigle
			logReplication.info("docid: " + docid);
1255 4080 daigle
			// Get revision number
1256
			int rev = Integer.parseInt((String) w.elementAt(1));
1257 5014 daigle
			logReplication.info("rev: " + rev);
1258 5175 daigle
			// Get remote server name (it is may not be doc home server because
1259 4080 daigle
			// the new hub feature
1260
			String remoteServer = (String) w.elementAt(2);
1261
			remoteServer = remoteServer.trim();
1262 2608 tao
1263 4080 daigle
			try {
1264
				if (tableName.equals(DocumentImpl.DOCUMENTTABLE)) {
1265
					handleDocInXMLDocuments(docid, rev, remoteServer, dataFile);
1266
				} else if (tableName.equals(DocumentImpl.REVISIONTABLE)) {
1267
					handleDocInXMLRevisions(docid, rev, remoteServer, dataFile);
1268
				} else {
1269
					continue;
1270
				}
1271 2608 tao
1272 4861 daigle
			} catch (Exception e) {
1273 5014 daigle
				logMetacat.error("ReplicationHandler.handleDocList - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1274
				logReplication.error("ReplicationHandler.handleDocList - error to handle update doc in " + tableName
1275 4861 daigle
						+ " in time replication" + e.getMessage());
1276 4080 daigle
				continue;
1277
			}
1278 5175 daigle
1279
	        if (_xmlDocQueryCount > 0 && (_xmlDocQueryCount % 100) == 0) {
1280
	        	logMetacat.debug("ReplicationHandler.update - xml_doc query count: " + _xmlDocQueryCount +
1281
	        			", xml_doc avg query time: " + (_xmlDocQueryTime / _xmlDocQueryCount));
1282
	        }
1283
1284
	        if (_xmlRevQueryCount > 0 && (_xmlRevQueryCount % 100) == 0) {
1285
	        	logMetacat.debug("ReplicationHandler.update - xml_rev query count: " + _xmlRevQueryCount +
1286
	        			", xml_rev avg query time: " + (_xmlRevQueryTime / _xmlRevQueryCount));
1287
	        }
1288 4080 daigle
1289
		}// for update docs
1290
1291
	}
1292 2608 tao
1293
   /*
1294 4080 daigle
	 * This method will handle doc in xml_documents table.
1295
	 */
1296 2608 tao
   private void handleDocInXMLDocuments(String docid, int rev, String remoteServer, boolean dataFile)
1297 5014 daigle
                                        throws HandlerException
1298 2608 tao
   {
1299
       // compare the update rev and local rev to see what need happen
1300
       int localrev = -1;
1301
       String action = null;
1302
       boolean flag = false;
1303
       try
1304
       {
1305 5175 daigle
    	 long docQueryStartTime = System.currentTimeMillis();
1306 2641 tao
         localrev = DBUtil.getLatestRevisionInDocumentTable(docid);
1307 5175 daigle
         long docQueryEndTime = System.currentTimeMillis();
1308
         _xmlDocQueryTime += (docQueryEndTime - docQueryStartTime);
1309
         _xmlDocQueryCount++;
1310 2608 tao
       }
1311
       catch (SQLException e)
1312
       {
1313 5014 daigle
    	 logMetacat.error("ReplicationHandler.handleDocInXMLDocuments - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1314
         logReplication.error("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " could not "+
1315 2663 sgarg
                                " be found because " + e.getMessage());
1316 5014 daigle
         logReplication.error("ReplicationHandler.handleDocInXMLDocuments - " + DOCERRORNUMBER+"Docid "+ docid + " could not be "+
1317 2608 tao
                 "written because error happend to find it's local revision");
1318 2739 tao
         DOCERRORNUMBER++;
1319 5014 daigle
         throw new HandlerException ("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " could not "+
1320
                 " be found: " + e.getMessage());
1321 2608 tao
       }
1322 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLDocuments - Local rev for docid "+ docid + " is "+
1323 2663 sgarg
                               localrev);
1324 2608 tao
1325
       //check the revs for an update because this document is in the
1326
       //local DB, it might be out of date.
1327
       if (localrev == -1)
1328
       {
1329 2713 tao
          // check if the revision is in the revision table
1330 5014 daigle
    	   Vector<Integer> localRevVector = null;
1331
    	 try {
1332 5175 daigle
        	 long revQueryStartTime = System.currentTimeMillis();
1333 5014 daigle
    		 localRevVector = DBUtil.getRevListFromRevisionTable(docid);
1334 5175 daigle
             long revQueryEndTime = System.currentTimeMillis();
1335
             _xmlRevQueryTime += (revQueryEndTime - revQueryStartTime);
1336
             _xmlRevQueryCount++;
1337 5014 daigle
    	 } catch (SQLException sqle) {
1338
    		 throw new HandlerException("ReplicationHandler.handleDocInXMLDocuments - SQL error "
1339
    				 + " when getting rev list for docid: " + docid + " : " + sqle.getMessage());
1340
    	 }
1341 2713 tao
         if (localRevVector != null && localRevVector.contains(new Integer(rev)))
1342
         {
1343
             // this version was deleted, so don't need replicate
1344
             flag = false;
1345
         }
1346
         else
1347
         {
1348
           //insert this document as new because it is not in the local DB
1349
           action = "INSERT";
1350
           flag = true;
1351
         }
1352 2608 tao
       }
1353
       else
1354
       {
1355
         if(localrev == rev)
1356
         {
1357
           // Local meatacat has the same rev to remote host, don't need
1358
           // update and flag set false
1359
           flag = false;
1360
         }
1361
         else if(localrev < rev)
1362
         {
1363
           //this document needs to be updated so send an read request
1364
           action = "UPDATE";
1365
           flag = true;
1366
         }
1367
       }
1368 2641 tao
1369 5014 daigle
       String accNumber = null;
1370
       try {
1371
    	   accNumber = docid + PropertyService.getProperty("document.accNumSeparator") + rev;
1372
       } catch (PropertyNotFoundException pnfe) {
1373
    	   throw new HandlerException("ReplicationHandler.handleDocInXMLDocuments - error getting "
1374
    			   + "account number separator : " + pnfe.getMessage());
1375
       }
1376 2608 tao
       // this is non-data file
1377
       if(flag && !dataFile)
1378
       {
1379
         try
1380
         {
1381 2641 tao
           handleSingleXMLDocument(remoteServer, action, accNumber, DocumentImpl.DOCUMENTTABLE);
1382 2608 tao
         }
1383 5014 daigle
         catch(HandlerException he)
1384 2608 tao
         {
1385
           // skip this document
1386 5014 daigle
           throw he;
1387 2608 tao
         }
1388
       }//if for non-data file
1389
1390
        // this is for data file
1391
       if(flag && dataFile)
1392
       {
1393
         try
1394
         {
1395 2641 tao
           handleSingleDataFile(remoteServer, action, accNumber, DocumentImpl.DOCUMENTTABLE);
1396 2608 tao
         }
1397 5014 daigle
         catch(HandlerException he)
1398 2608 tao
         {
1399 5175 daigle
           // skip this data file
1400 5014 daigle
           throw he;
1401 2608 tao
         }
1402
1403 5175 daigle
       }//for data file
1404 2608 tao
   }
1405
1406
   /*
1407
    * This method will handle doc in xml_documents table.
1408
    */
1409
   private void handleDocInXMLRevisions(String docid, int rev, String remoteServer, boolean dataFile)
1410 5014 daigle
                                        throws HandlerException
1411 2608 tao
   {
1412
       // compare the update rev and local rev to see what need happen
1413 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - In handle repliation revsion table");
1414
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - the docid is "+ docid);
1415
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - The rev is "+rev);
1416
       Vector<Integer> localrev = null;
1417 2608 tao
       String action = "INSERT";
1418
       boolean flag = false;
1419
       try
1420
       {
1421 5175 daigle
      	 long revQueryStartTime = System.currentTimeMillis();
1422 2608 tao
         localrev = DBUtil.getRevListFromRevisionTable(docid);
1423 5175 daigle
         long revQueryEndTime = System.currentTimeMillis();
1424
         _xmlRevQueryTime += (revQueryEndTime - revQueryStartTime);
1425
         _xmlRevQueryCount++;
1426 2608 tao
       }
1427 5014 daigle
       catch (SQLException sqle)
1428 2608 tao
       {
1429 5014 daigle
    	 logMetacat.error("ReplicationHandler.handleDocInXMLDocuments - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1430
         logReplication.error("ReplicationHandler.handleDocInXMLRevisions - Local rev for docid "+ docid + " could not "+
1431
                                " be found because " + sqle.getMessage());
1432 2739 tao
         REVERRORNUMBER++;
1433 5014 daigle
         throw new HandlerException ("ReplicationHandler.handleDocInXMLRevisions - SQL exception getting rev list: "
1434
        		 + sqle.getMessage());
1435 2608 tao
       }
1436 5014 daigle
       logReplication.info("ReplicationHandler.handleDocInXMLRevisions - rev list in xml_revision table for docid "+ docid + " is "+
1437 2663 sgarg
                               localrev.toString());
1438 2608 tao
1439
       // if the rev is not in the xml_revision, we need insert it
1440
       if (!localrev.contains(new Integer(rev)))
1441
       {
1442
           flag = true;
1443
       }
1444 2641 tao
1445 5014 daigle
       String accNumber = null;
1446
       try {
1447
    	   accNumber = docid + PropertyService.getProperty("document.accNumSeparator") + rev;
1448
       } catch (PropertyNotFoundException pnfe) {
1449
    	   throw new HandlerException("ReplicationHandler.handleDocInXMLRevisions - error getting "
1450
    			   + "account number separator : " + pnfe.getMessage());
1451
       }
1452 2608 tao
       // this is non-data file
1453
       if(flag && !dataFile)
1454
       {
1455
         try
1456
         {
1457 2641 tao
1458
           handleSingleXMLDocument(remoteServer, action, accNumber, DocumentImpl.REVISIONTABLE);
1459 2608 tao
         }
1460 5014 daigle
         catch(HandlerException he)
1461 2608 tao
         {
1462
           // skip this document
1463 5014 daigle
           throw he;
1464 2608 tao
         }
1465
       }//if for non-data file
1466
1467
        // this is for data file
1468
       if(flag && dataFile)
1469
       {
1470
         try
1471
         {
1472 2641 tao
           handleSingleDataFile(remoteServer, action, accNumber, DocumentImpl.REVISIONTABLE);
1473 2608 tao
         }
1474 5014 daigle
         catch(HandlerException he)
1475 2608 tao
         {
1476 5175 daigle
           // skip this data file
1477 5014 daigle
           throw he;
1478 2608 tao
         }
1479
1480 5175 daigle
       }//for data file
1481 2608 tao
   }
1482 3234 tao
1483
   /*
1484
    * Return a ip address for given url
1485
    */
1486
   private String getIpFromURL(URL url)
1487
   {
1488
	   String ip = null;
1489
	   try
1490
	   {
1491
	      InetAddress address = InetAddress.getByName(url.getHost());
1492
	      ip = address.getHostAddress();
1493
	   }
1494
	   catch(UnknownHostException e)
1495
	   {
1496 5014 daigle
		   logMetacat.error("ReplicationHandler.getIpFromURL - " + ReplicationService.METACAT_REPL_ERROR_MSG);
1497
		   logReplication.error("ReplicationHandler.getIpFromURL - Error in get ip address for host: "
1498 3234 tao
                   +e.getMessage());
1499
	   }
1500
1501
	   return ip;
1502
   }
1503 2608 tao
1504 522 berkley
}