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