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