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