Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements replication for metacat
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: tao $'
9
 *     '$Date: 2007-04-12 18:13:08 -0700 (Thu, 12 Apr 2007) $'
10
 * '$Revision: 3229 $'
11
 *
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
 */
26

    
27
package edu.ucsb.nceas.metacat;
28

    
29
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
30
import java.util.*;
31
import java.util.Date;
32
import java.io.*;
33
import java.sql.*;
34
import java.net.*;
35
import java.lang.*;
36
import java.text.*;
37
import javax.servlet.*;
38
import javax.servlet.http.*;
39

    
40
import org.apache.log4j.Logger;
41
import org.xml.sax.*;
42

    
43
public class MetacatReplication extends HttpServlet implements Runnable
44
{
45
  private long timeInterval;
46
  private Date firstTime;
47
  private boolean timedReplicationIsOn = false;
48
  Timer replicationDaemon;
49
  private static MetaCatUtil util = new MetaCatUtil();
50
  private Vector fileLocks = new Vector();
51
  private Thread lockThread = null;
52
  private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
53
  public static final String FORCEREPLICATEDELETE = "forcereplicatedelete";
54
  private static final String TIMEREPLICATION = "timedreplication";
55
  private static final String TIMEREPLICATIONINTERVAl = "timedreplicationinterval";
56
  private static final String FIRSTTIME  = "firsttimedreplication";
57
  private static final int    TIMEINTERVALLIMIT = 7200000;
58
  private static Logger logMetacat = Logger.getLogger(MetacatReplication.class);
59

    
60
  /**
61
   * Initialize the servlet by creating appropriate database connections
62
   */
63
  public void init(ServletConfig config) throws ServletException
64
  {
65
     //initialize db connections to handle any update requests
66
    MetaCatUtil util = new MetaCatUtil();
67
    //deltaT = util.getOption("deltaT");
68
    //the default deltaT can be set from metacat.properties
69
    //create a thread to do the delta-T check but don't execute it yet
70
    replicationDaemon = new Timer(true);
71
    try
72
    {
73
       timedReplicationIsOn = (new Boolean(util.getOption(TIMEREPLICATION ).trim())).booleanValue();
74
       logMetacat.info("The timed replication on is"+timedReplicationIsOn);
75
       timeInterval = (new Long(util.getOption(TIMEREPLICATIONINTERVAl).trim())).longValue();
76
       logMetacat.warn("The timed replication time Inerval is "+ timeInterval);
77
       String firstTimeStr = util.getOption(FIRSTTIME);
78
       logMetacat.warn("first replication time form property is "+firstTimeStr);
79
       firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
80
       logMetacat.warn("After combine current time, the real first time is "
81
                                +firstTime.toString()+" minisec");
82
       // set up time replication if it is on
83
       if (timedReplicationIsOn)
84
       {
85
           replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime, timeInterval);
86
           MetacatReplication.replLog("deltaT handler started with rate=" +
87
                   timeInterval + " mini seconds at " +firstTime.toString());
88
       }
89
    }
90
    catch (Exception e)
91
    {
92
        // the timed replication in Metacat.properties file has problem
93
        // so timed replication is setting to false;
94
        logMetacat.error("Couldn't set up timed replication "+
95
                     " in Metacat replication servlet init because " +
96
                 e.getMessage());
97
        MetacatReplication.replErrorLog("Couldn't set up timed replication "+
98
                " in Metacat replication servlet init because " +
99
                e.getMessage());
100
        timedReplicationIsOn = false;
101
    }
102
    
103
  }
104

    
105
  public void destroy()
106
  {
107
    replicationDaemon.cancel();
108
   
109
  }
110

    
111
  public void doGet (HttpServletRequest request, HttpServletResponse response)
112
                     throws ServletException, IOException
113
  {
114
    // Process the data and send back the response
115
    handleGetOrPost(request, response);
116
  }
117

    
118
  public void doPost(HttpServletRequest request, HttpServletResponse response)
119
                     throws ServletException, IOException
120
  {
121
    // Process the data and send back the response
122
    handleGetOrPost(request, response);
123
  }
124

    
125
  private void handleGetOrPost(HttpServletRequest request,
126
                               HttpServletResponse response)
127
                               throws ServletException, IOException
128
  {
129
    //PrintWriter out = response.getWriter();
130
    //ServletOutputStream outPut = response.getOutputStream();
131
    Hashtable params = new Hashtable();
132
    Enumeration paramlist = request.getParameterNames();
133

    
134

    
135

    
136
// NOT NEEDED - doesn't provide enough security because of possible IP spoofing
137
// REPLACED with running replication comminications over HTTPS
138
//    String requestingServerIP = request.getRemoteAddr();
139
//    InetAddress iaddr = InetAddress.getByName(requestingServerIP);
140
//    String requestingServer = iaddr.getHostName();
141

    
142
    while (paramlist.hasMoreElements()) {
143
      String name = (String)paramlist.nextElement();
144
      String[] value = request.getParameterValues(name);
145
      params.put(name, value);
146
    }
147

    
148
    String action = ((String[])params.get("action"))[0];
149
    String server = null;
150

    
151
    try {
152
      // check if the server is included in the list of replicated servers
153
      if ( !action.equals("servercontrol") &&
154
           !action.equals("stop") &&
155
           !action.equals("start") &&
156
           !action.equals("getall") ) {
157

    
158
        server = ((String[])params.get("server"))[0];
159
        if ( getServerCodeForServerName(server) == 0 ) {
160
          System.out.println("Action \"" + action +
161
                             "\" rejected for server: " + server);
162
          return;
163
        } else {
164
          System.out.println("Action \"" + action +
165
                             "\" accepted for server: " + server);
166
        }
167
      }
168
      else
169
      {
170
          // start, stop, getall and servercontrol need to check
171
          // if user is administor
172
          HttpSession sess = request.getSession(true);
173
          String sess_id = "";
174
          String username = "";
175
          String[] groupnames = {""};
176
          Hashtable sessionHash = MetaCatServlet.getSessionHash();
177
          if (params.containsKey("sessionid")) 
178
          {
179
             sess_id = ((String[]) params.get("sessionid"))[0];
180
             logMetacat.info("in has sessionid "+ sess_id);
181
             if (sessionHash.containsKey(sess_id)) 
182
             {
183
                  logMetacat.info("find the id " + sess_id + " in hash table");
184
                  sess = (HttpSession) sessionHash.get(sess_id);
185
             }
186
           } 
187
           username = (String) sess.getAttribute("username");
188
           logMetacat.warn("The user name from session is: "+ username);
189
           groupnames = (String[]) sess.getAttribute("groupnames");
190
           if (!MetaCatUtil.isAdministrator(username, groupnames)) 
191
           {
192
               PrintWriter out = response.getWriter();
193
               out.print("<error>");
194
               out.print("The user \"" + username +
195
                       "\" is not authorized for this action.");
196
               out.print("</error>");
197
               out.close();
198
               logMetacat.warn("The user \"" + username +
199
                       "\" is not authorized for this action: " +action);
200
               replErrorLog("The user \"" + username +
201
                       "\" is not authorized for this action: " +action);
202
               return;
203
           }
204
                        
205
      }// this is final else
206
    } catch (Exception e) {
207
      System.out.println("Error in MetacatReplication.handleGetOrPost: " +
208
                         e.getMessage() );
209
      return;
210
    }
211
    
212
    if ( action.equals("readdata") )
213
    {
214
      OutputStream outStream = response.getOutputStream();
215
      //to get the data file.
216
      handleGetDataFileRequest(outStream, params, response);
217
      outStream.close();
218
    }
219
    else if ( action.equals("forcereplicatedatafile") )
220
    {
221
      //read a specific docid from remote host, and store it into local host
222
      handleForceReplicateDataFileRequest(params);
223

    
224
    }
225
    else
226
    {
227
    PrintWriter out = response.getWriter();
228
    if ( action.equals("stop") ) {
229
      //stop the replication server
230
      replicationDaemon.cancel();
231
      replicationDaemon = new Timer(true);
232
      timedReplicationIsOn = false;
233
      MetaCatUtil.setOption(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
234
      out.println("Replication Handler Stopped");
235
      MetacatReplication.replLog("deltaT handler stopped");
236

    
237

    
238
    } else if ( action.equals("start") ) {
239
       String firstTimeStr = "";
240
      //start the replication server
241
       if ( params.containsKey("rate") ) {
242
        timeInterval = new Long(
243
               new String(((String[])params.get("rate"))[0])).longValue();
244
        if(timeInterval < TIMEINTERVALLIMIT) {
245
            out.println("Replication deltaT rate cannot be less than "+
246
                    TIMEINTERVALLIMIT + " millisecs and system automatically setup the rate to "+TIMEINTERVALLIMIT);
247
            //deltaT<30 is a timing mess!
248
            timeInterval = TIMEINTERVALLIMIT;
249
        }
250
      } else {
251
        timeInterval = TIMEINTERVALLIMIT ;
252
      }
253
      logMetacat.info("New rate is: " + timeInterval + " mini seconds.");
254
      if ( params.containsKey("firsttime"))
255
      {
256
         firstTimeStr = ((String[])params.get("firsttime"))[0];
257
         try
258
         {
259
           firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
260
           logMetacat.info("The first time setting is "+firstTime.toString());
261
         }
262
         catch (Exception e)
263
         {
264
            throw new ServletException(e.getMessage());
265
         }
266
         logMetacat.warn("After combine current time, the real first time is "
267
                                  +firstTime.toString()+" minisec");
268
      }
269
      else
270
      {
271
          MetacatReplication.replErrorLog("You should specify the first time " +
272
                                          "to start a time replication");
273
          logMetacat.warn("You should specify the first time " +
274
                                  "to start a time replication");
275
          return;
276
      }
277
      
278
      timedReplicationIsOn = true;
279
      // save settings to property file
280
      MetaCatUtil.setOption(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
281
      // note we couldn't use firstTime object because it has date info
282
      // we only need time info such as 10:00 PM
283
      MetaCatUtil.setOption(FIRSTTIME, firstTimeStr);
284
      MetaCatUtil.setOption(TIMEREPLICATIONINTERVAl, (new Long(timeInterval)).toString());
285
      replicationDaemon.cancel();
286
      replicationDaemon = new Timer(true);
287
      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime,
288
                                            timeInterval);
289
      out.println("Replication Handler Started");
290
      MetacatReplication.replLog("deltaT handler started with rate=" +
291
                                    timeInterval + " milliseconds at " +firstTime.toString());
292

    
293

    
294
    } else if ( action.equals("getall") ) {
295
      //updates this server exactly once
296
      replicationDaemon.schedule(new ReplicationHandler(), 0);
297
      response.setContentType("text/html");
298
      out.println("<html><body>\"Get All\" Done</body></html>");
299

    
300
    } else if ( action.equals("forcereplicate") ) {
301
      //read a specific docid from remote host, and store it into local host
302
      handleForceReplicateRequest(out, params, response);
303

    
304
    } else if ( action.equals(FORCEREPLICATEDELETE) ) {
305
      //read a specific docid from remote host, and store it into local host
306
      handleForceReplicateDeleteRequest(out, params, response);
307

    
308
    } else if ( action.equals("update") ) {
309
      //request an update list from the server
310
      handleUpdateRequest(out, params, response);
311

    
312
    } else if ( action.equals("read") ) {
313
      //request a specific document from the server
314
      //note that this could be replaced by a call to metacatServlet
315
      //handleGetDocumentAction().
316
      handleGetDocumentRequest(out, params, response);
317
    } else if ( action.equals("getlock") ) {
318
      handleGetLockRequest(out, params, response);
319

    
320
    } else if ( action.equals("getdocumentinfo") ) {
321
      handleGetDocumentInfoRequest(out, params, response);
322

    
323
    } else if ( action.equals("gettime") ) {
324
      handleGetTimeRequest(out, params, response);
325

    
326
    } else if ( action.equals("getcatalog") ) {
327
      handleGetCatalogRequest(out, params, response, true);
328

    
329
    } else if ( action.equals("servercontrol") ) {
330
      handleServerControlRequest(out, params, response);
331
    } else if ( action.equals("test") ) {
332
      response.setContentType("text/html");
333
      out.println("<html><body>Test successfully</body></html>");
334
    }
335

    
336
    out.close();
337
    }//else
338
  }
339

    
340
  /**
341
   * This method can add, delete and list the servers currently included in
342
   * xml_replication.
343
   * action           subaction            other needed params
344
   * ---------------------------------------------------------
345
   * servercontrol    add                  server
346
   * servercontrol    delete               server
347
   * servercontrol    list
348
   */
349
  private void handleServerControlRequest(PrintWriter out, Hashtable params,
350
                                          HttpServletResponse response)
351
  {
352
    String subaction = ((String[])params.get("subaction"))[0];
353
    DBConnection dbConn = null;
354
    int serialNumber = -1;
355
    PreparedStatement pstmt = null;
356
    String replicate =null;
357
    String server = null;
358
    String dataReplicate = null;
359
    String hub = null;
360
    try {
361
      //conn = util.openDBConnection();
362
      dbConn=DBConnectionPool.
363
               getDBConnection("MetacatReplication.handleServerControlRequest");
364
      serialNumber=dbConn.getCheckOutSerialNumber();
365

    
366
      // add server to server list
367
      if ( subaction.equals("add") ) {
368
        replicate = ((String[])params.get("replicate"))[0];
369
        server = ((String[])params.get("server"))[0];
370

    
371
        //Get data replication value
372
        dataReplicate = ((String[])params.get("datareplicate"))[0];
373
        //Get hub value
374
        hub = ((String[])params.get("hub"))[0];
375

    
376
        /*pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
377
                  "(server, last_checked, replicate, datareplicate, hub) " +
378
                                      "VALUES ('" + server + "', to_date(" +
379
                                      "'01/01/00', 'MM/DD/YY'), '" +
380
                                      replicate +"', '" +dataReplicate+"', '"
381
                                      + hub +"')");*/
382
        pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
383
                  "(server, last_checked, replicate, datareplicate, hub) " +
384
                                      "VALUES ('" + server + "', "+
385
                                      dbAdapter.toDate("01/01/1980", "MM/DD/YYYY")
386
                                      + ", '" +
387
                                      replicate +"', '" +dataReplicate+"', '"
388
                                      + hub +"')");
389

    
390
        pstmt.execute();
391
        pstmt.close();
392
        dbConn.commit();
393
        out.println("Server " + server + " added");
394
        response.setContentType("text/html");
395
        out.println("<html><body><table border=\"1\">");
396
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
397
        out.println("<b>replicate</b></td>");
398
        out.println("<td><b>datareplicate</b></td>");
399
        out.println("<td><b>hub</b></td></tr>");
400
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
401
        //increase dbconnection usage
402
        dbConn.increaseUsageCount(1);
403

    
404
        pstmt.execute();
405
        ResultSet rs = pstmt.getResultSet();
406
        boolean tablehasrows = rs.next();
407
        while(tablehasrows) {
408
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
409
          out.println(rs.getString(3) + "</td><td>");
410
          out.println(rs.getString(4) + "</td><td>");
411
          out.println(rs.getString(5) + "</td><td>");
412
          out.println(rs.getString(6) + "</td></tr>");
413

    
414
          tablehasrows = rs.next();
415
        }
416
        out.println("</table></body></html>");
417

    
418
        // download certificate with the public key on this server
419
        // and import it as a trusted certificate
420
        String certURL = ((String[])params.get("certificate"))[0];
421
        downloadCertificate(certURL);
422

    
423
      // delete server from server list
424
      } else if ( subaction.equals("delete") ) {
425
        server = ((String[])params.get("server"))[0];
426
        pstmt = dbConn.prepareStatement("DELETE FROM xml_replication " +
427
                                      "WHERE server LIKE '" + server + "'");
428
        pstmt.execute();
429
        pstmt.close();
430
        dbConn.commit();
431
        out.println("Server " + server + " deleted");
432
        response.setContentType("text/html");
433
        out.println("<html><body><table border=\"1\">");
434
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
435
        out.println("<b>replicate</b></td>");
436
        out.println("<td><b>datareplicate</b></td>");
437
        out.println("<td><b>hub</b></td></tr>");
438

    
439
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
440
        //increase dbconnection usage
441
        dbConn.increaseUsageCount(1);
442
        pstmt.execute();
443
        ResultSet rs = pstmt.getResultSet();
444
        boolean tablehasrows = rs.next();
445
        while(tablehasrows)
446
        {
447
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
448
          out.println(rs.getString(3) + "</td><td>");
449
          out.println(rs.getString(4) + "</td><td>");
450
          out.println(rs.getString(5) + "</td><td>");
451
          out.println(rs.getString(6) + "</td></tr>");
452
          tablehasrows = rs.next();
453
        }
454
        out.println("</table></body></html>");
455

    
456
      // list servers in server list
457
      } else if ( subaction.equals("list") ) {
458
        response.setContentType("text/html");
459
        out.println("<html><body><table border=\"1\">");
460
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
461
        out.println("<b>replicate</b></td>");
462
        out.println("<td><b>datareplicate</b></td>");
463
        out.println("<td><b>hub</b></td></tr>");
464
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
465
        pstmt.execute();
466
        ResultSet rs = pstmt.getResultSet();
467
        boolean tablehasrows = rs.next();
468
        while(tablehasrows) {
469
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
470
          out.println(rs.getString(3) + "</td><td>");
471
          out.println(rs.getString(4) + "</td><td>");
472
          out.println(rs.getString(5) + "</td><td>");
473
          out.println(rs.getString(6) + "</td></tr>");
474
          tablehasrows = rs.next();
475
        }
476
        out.println("</table></body></html>");
477
      }
478
      else
479
      {
480

    
481
        out.println("<error>Unkonwn subaction</error>");
482

    
483
      }
484
      pstmt.close();
485
      //conn.close();
486

    
487
    } catch(Exception e) {
488
      System.out.println("Error in " +
489
                         "MetacatReplication.handleServerControlRequest " +
490
                         e.getMessage());
491
      e.printStackTrace(System.out);
492
    }
493
    finally
494
    {
495
      try
496
      {
497
        pstmt.close();
498
      }//try
499
      catch (SQLException ee)
500
      {
501
        logMetacat.error("Error in " +
502
                "MetacatReplication.handleServerControlRequest to close pstmt "
503
                 + ee.getMessage());
504
      }//catch
505
      finally
506
      {
507
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
508
      }//finally
509
    }//finally
510

    
511
  }
512

    
513
  // download certificate with the public key from certURL and
514
  // upload it onto this server; it then must be imported as a
515
  // trusted certificate
516
  private void downloadCertificate (String certURL)
517
                throws FileNotFoundException, IOException, MalformedURLException
518
  {
519
    MetaCatUtil util = new MetaCatUtil();
520
    String certPath = util.getOption("certPath"); //the path to be uploaded to
521

    
522
    // get filename from the URL of the certificate
523
    String filename = certURL;
524
    int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
525
    if ( slash > -1 ) {
526
      filename = filename.substring(slash + 1);
527
    }
528

    
529
    // open file output strem to write the input into it
530
    File f = new File(certPath, filename);
531
    synchronized (f) {
532
      try {
533
        if ( f.exists() ) {
534
          throw new IOException("File already exist: " + f.getCanonicalFile());
535
          //if ( f.exists() && !f.canWrite() ) {
536
          //  throw new IOException("Not writable: " + f.getCanonicalFile());
537
        }
538
      } catch (SecurityException se) {
539
        // if a security manager exists,
540
        // its checkRead method is called for f.exist()
541
        // or checkWrite method is called for f.canWrite()
542
        throw se;
543
      }
544

    
545
      // create a buffered byte output stream
546
      // that uses a default-sized output buffer
547
      FileOutputStream fos = new FileOutputStream(f);
548
      BufferedOutputStream out = new BufferedOutputStream(fos);
549

    
550
      // this should be http url
551
      URL url = new URL(certURL);
552
      BufferedInputStream bis = null;
553
      try {
554
        bis = new BufferedInputStream(url.openStream());
555
        byte[] buf = new byte[4 * 1024]; // 4K buffer
556
        int b = bis.read(buf);
557
        while (b != -1) {
558
          out.write(buf, 0, b);
559
          b = bis.read(buf);
560
        }
561
      } finally {
562
        if (bis != null) bis.close();
563
      }
564
      // the input and the output streams must be closed
565
      bis.close();
566
            out.flush();
567
            out.close();
568
            fos.close();
569
    } // end of synchronized(f)
570
  }
571

    
572
  /**
573
   * when a forcereplication request comes in, local host sends a read request
574
   * to the requesting server (remote server) for the specified docid.
575
   * Then store it in local database.
576
   */
577
  private void handleForceReplicateRequest(PrintWriter out, Hashtable params,
578
                                           HttpServletResponse response)
579
  {
580
    String server = ((String[])params.get("server"))[0]; // the server that
581
    String docid = ((String[])params.get("docid"))[0]; // sent the document
582
    String ipAddress = ((String[])params.get("ipAddress"))[0];
583
    String dbaction = "UPDATE"; // the default action is UPDATE
584
    boolean override = false;
585
    int serverCode = 1;
586
    DBConnection dbConn = null;
587
    int serialNumber = -1;
588

    
589
    try {
590
      //if the url contains a dbaction then the default action is overridden
591
      if(params.containsKey("dbaction")) {
592
        dbaction = ((String[])params.get("dbaction"))[0];
593
        //serverCode = MetacatReplication.getServerCode(server);
594
        //override = true; //we are now overriding the default action
595
      }
596
      MetacatReplication.replLog("force replication request from " + server);
597
      logMetacat.info("Force replication request from: "+ server);
598
      logMetacat.info("Force replication docid: "+docid);
599
      logMetacat.info("Force replication action: "+dbaction);
600
      // sending back read request to remote server
601
      URL u = new URL("https://" + server + "?server="
602
                +util.getLocalReplicationServerName()
603
                +"&action=read&docid=" + docid);
604
      String xmldoc = MetacatReplication.getURLContent(u);
605

    
606
      // get the document info from server
607
      URL docinfourl = new URL("https://" + server +
608
                               "?server="+util.getLocalReplicationServerName()
609
                               +"&action=getdocumentinfo&docid=" + docid);
610

    
611
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
612

    
613
      //dih is the parser for the docinfo xml format
614
      DocInfoHandler dih = new DocInfoHandler();
615
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
616
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
617
      Hashtable docinfoHash = dih.getDocInfo();
618

    
619
      // Get user owner of this docid
620
      String user = (String)docinfoHash.get("user_owner");
621
      // Get home server of this docid
622
      String homeServer=(String)docinfoHash.get("home_server");
623
      String createdDate = (String)docinfoHash.get("date_created");
624
      String updatedDate = (String)docinfoHash.get("date_updated");
625
      logMetacat.info("homeServer: "+homeServer);
626
      // Get Document type
627
      String docType = (String)docinfoHash.get("doctype");
628
      logMetacat.info("docType: "+docType);
629
      String parserBase = null;
630
      // this for eml2 and we need user eml2 parser
631
      if (docType != null &&
632
          (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
633
      {
634
         logMetacat.warn("This is an eml200 document!");
635
         parserBase = DocumentImpl.EML200;
636
      }
637
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE))
638
      {
639
         logMetacat.warn("This is an eml2.0.1 document!");
640
         parserBase = DocumentImpl.EML200;
641
      }
642
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE))
643
      {
644
         logMetacat.warn("This is an eml2.1.0 document!");
645
         parserBase = DocumentImpl.EML210;
646
      }
647
      logMetacat.warn("The parserBase is: "+parserBase);
648

    
649
      // Get DBConnection from pool
650
      dbConn=DBConnectionPool.
651
              getDBConnection("MetacatReplication.handleForceReplicateRequest");
652
      serialNumber=dbConn.getCheckOutSerialNumber();
653
      // write the document to local database
654
      DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false);
655
      wrapper.writeReplication(dbConn, new StringReader(xmldoc), null, null,
656
                               dbaction, docid, user, null, homeServer, 
657
                               server, createdDate, updatedDate, ipAddress);
658
      
659
      MetacatReplication.replLog("document " + docid + " added to DB with " +
660
                                 "action " + dbaction);
661
      EventLog.getInstance().log(ipAddress, user, docid, dbaction);
662
    }//try
663
    catch(Exception e)
664
    {
665
      MetacatReplication.replErrorLog("document " + docid +
666
                                      " failed to added to DB with " +
667
                                      "action " + dbaction + " because "+
668
                                       e.getMessage());
669
      logMetacat.error("ERROR in MetacatReplication.handleForceReplicate" +
670
                         "Request(): " + e.getMessage());
671
      
672

    
673
    }//catch
674
    finally
675
    {
676
      // Return the checked out DBConnection
677
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
678
    }//finally
679
  }
680

    
681
/*
682
 * when a forcereplication delete request comes in, local host will delete this
683
 * document
684
 */
685
private void handleForceReplicateDeleteRequest(PrintWriter out, Hashtable params,
686
                                         HttpServletResponse response)
687
{
688
  String server = ((String[])params.get("server"))[0]; // the server that
689
  String docid = ((String[])params.get("docid"))[0]; // sent the document
690
  String user = ((String[])params.get("user"))[0];
691
  String ipAddress = ((String[])params.get("ipAddress"))[0];
692
  try
693
  {
694
    MetacatReplication.replLog("force replication delete request from " + server);
695
    MetacatReplication.replLog("force replication delete docid " + docid);
696
    logMetacat.info("Force replication delete request from: "+ server);
697
    logMetacat.info("Force replication delete docid: "+docid);
698
    DocumentImpl.delete(docid, null, null, server, ipAddress);
699
    MetacatReplication.replLog("document " + docid + " was successfully deleted ");
700
    EventLog.getInstance().log(ipAddress, user, docid, "delete");
701
    logMetacat.info("document " + docid + " was successfully deleted ");
702
  }
703
  catch(Exception e)
704
  {
705
    MetacatReplication.replErrorLog("document " + docid +
706
                                    " failed to delete because "+
707
                                     e.getMessage());
708
    logMetacat.error("ERROR in MetacatReplication.handleForceDeleteReplicate" +
709
                       "Request(): " + e.getMessage());
710

    
711
  }//catch
712

    
713
}
714

    
715

    
716
  /**
717
   * when a forcereplication data file request comes in, local host sends a
718
   * readdata request to the requesting server (remote server) for the specified
719
   * docid. Then store it in local database and file system
720
   */
721
  private void handleForceReplicateDataFileRequest(Hashtable params)
722
  {
723

    
724
    //make sure there is some parameters
725
    if(params.isEmpty())
726
    {
727
      return;
728
    }
729
    // Get remote server
730
    String server = ((String[])params.get("server"))[0];
731
    // the docid should include rev number
732
    String docid = ((String[])params.get("docid"))[0];
733
    String ipAddress = ((String[])params.get("ipAddress"))[0];
734
    // Make sure there is a docid and server
735
    if (docid==null || server==null || server.equals(""))
736
    {
737
      logMetacat.error("Didn't specify docid or server for replication");
738
      return;
739
    }
740

    
741
    // Overide or not
742
    boolean override = false;
743
    // dbaction - update or insert
744
    String dbaction=null;
745

    
746
    try
747
    {
748
      //docid was switch to two parts uinque code and rev
749
      //String uniqueCode=MetaCatUtil.getDocIdFromString(docid);
750
      //int rev=MetaCatUtil.getVersionFromString(docid);
751
      if(params.containsKey("dbaction"))
752
      {
753
        dbaction = ((String[])params.get("dbaction"))[0];
754
      }
755
      else//default value is update
756
      {
757
        dbaction = "update";
758
      }
759

    
760
      MetacatReplication.replLog("force replication request from " + server);
761
      logMetacat.info("Force replication request from: "+ server);
762
      logMetacat.info("Force replication docid: "+docid);
763
      logMetacat.info("Force replication action: "+dbaction);
764
      // get the document info from server
765
      URL docinfourl = new URL("https://" + server +
766
                               "?server="+util.getLocalReplicationServerName()
767
                               +"&action=getdocumentinfo&docid=" + docid);
768

    
769
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
770

    
771
      //dih is the parser for the docinfo xml format
772
      DocInfoHandler dih = new DocInfoHandler();
773
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
774
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
775
      Hashtable docinfoHash = dih.getDocInfo();
776
      String user = (String)docinfoHash.get("user_owner");
777

    
778
      String docName = (String)docinfoHash.get("docname");
779

    
780
      String docType = (String)docinfoHash.get("doctype");
781

    
782
      String docHomeServer= (String)docinfoHash.get("home_server");
783
      
784
      String createdDate = (String)docinfoHash.get("date_created");
785
      
786
      String updatedDate = (String)docinfoHash.get("date_updated");
787
      logMetacat.info("docHomeServer of datafile: "+docHomeServer);
788

    
789

    
790

    
791
      //if action is delete, we don't delete the data file. Just archieve
792
      //the xml_documents
793
      /*if (dbaction.equals("delete"))
794
      {
795
        //conn = util.getConnection();
796
        DocumentImpl.delete(docid,user,null);
797
        //util.returnConnection(conn);
798
      }*/
799
      //To data file insert or update is same
800
      if (dbaction.equals("insert")||dbaction.equals("update"))
801
      {
802
        //Get data file and store it into local file system.
803
        // sending back readdata request to server
804
        URL url = new URL("https://" + server + "?server="
805
                +util.getLocalReplicationServerName()
806
                +"&action=readdata&docid=" + docid);
807
        String datafilePath = util.getOption("datafilepath");
808
        //register data file into xml_documents table and wite data file
809
        //into file system
810
        DocumentImpl.writeDataFileInReplication(url.openStream(), datafilePath,
811
                            docName, docType, docid, user,docHomeServer,server, 
812
                            DocumentImpl.DOCUMENTTABLE, false, createdDate, updatedDate, ipAddress);
813
                            //false means non-timed replication
814
     }
815

    
816

    
817

    
818
    MetacatReplication.replLog("datafile " + docid + " added to DB with " +
819
                                 "action " + dbaction);
820
    EventLog.getInstance().log(ipAddress, user, docid, dbaction);
821
    }
822
    catch(Exception e)
823
    {
824

    
825
      MetacatReplication.replErrorLog("Datafile " + docid +
826
                                      " failed to added to DB with " +
827
                                      "action " + dbaction + " because "+
828
                                       e.getMessage());
829
      logMetacat.error
830
              ("ERROR in MetacatReplication.handleForceDataFileReplicate" +
831
                         "Request(): " + e.getMessage());
832
    }
833
  }
834
  /**
835
   * Grants or denies a lock to a requesting host.
836
   * The servlet parameters of interrest are:
837
   * docid: the docid of the file the lock is being requested for
838
   * currentdate: the timestamp of the document on the remote server
839
   *
840
   */
841
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
842
                                    HttpServletResponse response)
843
  {
844

    
845
    try
846
    {
847

    
848
      String docid = ((String[])params.get("docid"))[0];
849
      String remoteRev = ((String[])params.get("updaterev"))[0];
850
      DocumentImpl requestDoc = new DocumentImpl(docid);
851
      MetacatReplication.replLog("lock request for " + docid);
852
      int localRevInt = requestDoc.getRev();
853
      int remoteRevInt = Integer.parseInt(remoteRev);
854

    
855
      if(remoteRevInt >= localRevInt)
856
      {
857
        if(!fileLocks.contains(docid))
858
        { //grant the lock if it is not already locked
859
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
860
          //send a message back to the the remote host authorizing the insert
861
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
862
          lockThread = new Thread(this);
863
          lockThread.setPriority(Thread.MIN_PRIORITY);
864
          lockThread.start();
865
          MetacatReplication.replLog("lock granted for " + docid);
866
        }
867
        else
868
        { //deny the lock
869
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
870
          MetacatReplication.replLog("lock denied for " + docid +
871
                                     "reason: file already locked");
872
        }
873
      }
874
      else
875
      {//deny the lock.
876
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
877
        MetacatReplication.replLog("lock denied for " + docid +
878
                                   "reason: client has outdated file");
879
      }
880
      //conn.close();
881
    }
882
    catch(Exception e)
883
    {
884
      System.out.println("error requesting file lock from MetacatReplication." +
885
                         "handleGetLockRequest: " + e.getMessage());
886
      e.printStackTrace(System.out);
887
    }
888
  }
889

    
890
  /**
891
   * Sends all of the xml_documents information encoded in xml to a requestor
892
   * the format is:
893
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
894
   *                  user_updated, home_server, public_access, rev)/>
895
   * all of the subelements of document info are #PCDATA
896
   */
897
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params,
898
                                        HttpServletResponse response)
899
  {
900
    String docid = ((String[])(params.get("docid")))[0];
901
    StringBuffer sb = new StringBuffer();
902

    
903
    try
904
    {
905

    
906
      DocumentImpl doc = new DocumentImpl(docid);
907
      sb.append("<documentinfo><docid>").append(docid);
908
      sb.append("</docid><docname>").append(doc.getDocname());
909
      sb.append("</docname><doctype>").append(doc.getDoctype());
910
      sb.append("</doctype>");
911
      sb.append("<user_owner>").append(doc.getUserowner());
912
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
913
      sb.append("</user_updated>");
914
      sb.append("<date_created>");
915
      sb.append(doc.getCreateDate());
916
      sb.append("</date_created>");
917
      sb.append("<date_updated>");
918
      sb.append(doc.getUpdateDate());
919
      sb.append("</date_updated>");
920
      sb.append("<home_server>");
921
      sb.append(doc.getDocHomeServer());
922
      sb.append("</home_server>");
923
      sb.append("<public_access>").append(doc.getPublicaccess());
924
      sb.append("</public_access><rev>").append(doc.getRev());
925
      sb.append("</rev></documentinfo>");
926
      response.setContentType("text/xml");
927
      out.println(sb.toString());
928

    
929
    }
930
    catch (Exception e)
931
    {
932
      System.out.println("error in " +
933
                         "metacatReplication.handlegetdocumentinforequest: " +
934
                          e.getMessage());
935
    }
936

    
937
  }
938

    
939
  /**
940
   * Sends a datafile to a remote host
941
   */
942
  private void handleGetDataFileRequest(OutputStream outPut,
943
                            Hashtable params, HttpServletResponse response)
944

    
945
  {
946
    // File path for data file
947
    String filepath = util.getOption("datafilepath");
948
    // Request docid
949
    String docId = ((String[])(params.get("docid")))[0];
950
    //check if the doicd is null
951
    if (docId==null)
952
    {
953
      logMetacat.error("Didn't specify docid for replication");
954
      return;
955
    }
956

    
957
    //try to open a https stream to test if the request server's public key
958
    //in the key store, this is security issue
959
    try
960
    {
961
      String server = ((String[])params.get("server"))[0];
962
      URL u = new URL("https://" + server + "?server="
963
                +util.getLocalReplicationServerName()
964
                +"&action=test");
965
      String test = MetacatReplication.getURLContent(u);
966
      //couldn't pass the test
967
      if (test.indexOf("successfully")==-1)
968
      {
969
        //response.setContentType("text/xml");
970
        //outPut.println("<error>Couldn't pass the trust test</error>");
971
        logMetacat.error("Couldn't pass the trust test");
972
        return;
973
      }
974
    }//try
975
    catch (Exception ee)
976
    {
977
      return;
978
    }//catch
979

    
980
    if(!filepath.endsWith("/"))
981
    {
982
          filepath += "/";
983
    }
984
    // Get file aboslute file name
985
    String filename = filepath + docId;
986

    
987
    //MIME type
988
    String contentType = null;
989
    if (filename.endsWith(".xml"))
990
    {
991
        contentType="text/xml";
992
    }
993
    else if (filename.endsWith(".css"))
994
    {
995
        contentType="text/css";
996
    }
997
    else if (filename.endsWith(".dtd"))
998
    {
999
        contentType="text/plain";
1000
    }
1001
    else if (filename.endsWith(".xsd"))
1002
    {
1003
        contentType="text/xml";
1004
    }
1005
    else if (filename.endsWith("/"))
1006
    {
1007
        contentType="text/html";
1008
    }
1009
    else
1010
    {
1011
        File f = new File(filename);
1012
        if ( f.isDirectory() )
1013
        {
1014
           contentType="text/html";
1015
        }
1016
        else
1017
        {
1018
           contentType="application/octet-stream";
1019
        }
1020
     }
1021

    
1022
   // Set the mime type
1023
   response.setContentType(contentType);
1024

    
1025
   // Get the content of the file
1026
   FileInputStream fin = null;
1027
   try
1028
   {
1029
      // FileInputStream to metacat
1030
      fin = new FileInputStream(filename);
1031
      // 4K buffer
1032
      byte[] buf = new byte[4 * 1024];
1033
      // Read data from file input stream to byte array
1034
      int b = fin.read(buf);
1035
      // Write to outStream from byte array
1036
      while (b != -1)
1037
      {
1038
        outPut.write(buf, 0, b);
1039
        b = fin.read(buf);
1040
      }
1041
      // close file input stream
1042
      fin.close();
1043

    
1044
   }//try
1045
   catch(Exception e)
1046
   {
1047
      System.out.println("error getting data file from MetacatReplication." +
1048
                         "handlGetDataFileRequest " + e.getMessage());
1049
      e.printStackTrace(System.out);
1050
   }//catch
1051

    
1052
}
1053

    
1054

    
1055
  /**
1056
   * Sends a document to a remote host
1057
   */
1058
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params,
1059
                                        HttpServletResponse response)
1060
  {
1061

    
1062
    try
1063
    {
1064
      //try to open a https stream to test if the request server's public key
1065
      //in the key store, this is security issue
1066
      String server = ((String[])params.get("server"))[0];
1067
      URL u = new URL("https://" + server + "?server="
1068
                +util.getLocalReplicationServerName()
1069
                +"&action=test");
1070
      String test = MetacatReplication.getURLContent(u);
1071
      //couldn't pass the test
1072
      if (test.indexOf("successfully")==-1)
1073
      {
1074
        response.setContentType("text/xml");
1075
        out.println("<error>Couldn't pass the trust test "+test+" </error>");
1076
        out.close();
1077
        return;
1078
      }
1079

    
1080
      String docid = ((String[])(params.get("docid")))[0];
1081

    
1082
      DocumentImpl di = new DocumentImpl(docid);
1083
      response.setContentType("text/xml");
1084
      out.print(di.toString(null, null, true));
1085

    
1086
      MetacatReplication.replLog("document " + docid + " sent");
1087

    
1088
    }
1089
    catch(Exception e)
1090
    {
1091
      logMetacat.error("error getting document from MetacatReplication."
1092
                          +"handlGetDocumentRequest " + e.getMessage());
1093
      //e.printStackTrace(System.out);
1094
      response.setContentType("text/xml");
1095
      out.println("<error>"+e.getMessage()+"</error>");
1096
    }
1097

    
1098
  }
1099

    
1100
  /**
1101
   * Sends a list of all of the documents on this sever along with their
1102
   * revision numbers.
1103
   * The format is:
1104
   * <!ELEMENT replication (server, updates)>
1105
   * <!ELEMENT server (#PCDATA)>
1106
   * <!ELEMENT updates ((updatedDocument | deleteDocument | revisionDocument)*)>
1107
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
1108
   * <!ELEMENT deletedDocument (docid, rev)>
1109
   * <!ELEMENT revisionDocument (docid, rev, datafile*)>
1110
   * <!ELEMENT docid (#PCDATA)>
1111
   * <!ELEMENT rev (#PCDATA)>
1112
   * <!ELEMENT datafile (#PCDATA)>
1113
   * note that the rev in deletedDocument is always empty.  I just left
1114
   * it in there to make the parser implementation easier.
1115
   */
1116
  private void handleUpdateRequest(PrintWriter out, Hashtable params,
1117
                                    HttpServletResponse response)
1118
  {
1119
    // Checked out DBConnection
1120
    DBConnection dbConn = null;
1121
    // DBConenction serial number when checked it out
1122
    int serialNumber = -1;
1123
    PreparedStatement pstmt = null;
1124
    // Server list to store server info of xml_replication table
1125
    ReplicationServerList serverList = null;
1126

    
1127
    try
1128
    {
1129
      // Check out a DBConnection from pool
1130
      dbConn=DBConnectionPool.
1131
                  getDBConnection("MetacatReplication.handleUpdateRequest");
1132
      serialNumber=dbConn.getCheckOutSerialNumber();
1133
      // Create a server list from xml_replication table
1134
      serverList = new ReplicationServerList();
1135

    
1136
      // Get remote server name from param
1137
      String server = ((String[])params.get("server"))[0];
1138
      // If no servr name in param, return a error
1139
      if ( server == null || server.equals(""))
1140
      {
1141
        response.setContentType("text/xml");
1142
        out.println("<error>Request didn't specify server name</error>");
1143
        out.close();
1144
        return;
1145
      }//if
1146

    
1147
      //try to open a https stream to test if the request server's public key
1148
      //in the key store, this is security issue
1149
      URL u = new URL("https://" + server + "?server="
1150
                +util.getLocalReplicationServerName()
1151
                +"&action=test");
1152
      String test = MetacatReplication.getURLContent(u);
1153
      //couldn't pass the test
1154
      if (test.indexOf("successfully")==-1)
1155
      {
1156
        response.setContentType("text/xml");
1157
        out.println("<error>Couldn't pass the trust test</error>");
1158
        out.close();
1159
        return;
1160
      }
1161

    
1162

    
1163
      // Check if local host configure to replicate xml documents to remote
1164
      // server. If not send back a error message
1165
      if (!serverList.getReplicationValue(server))
1166
      {
1167
        response.setContentType("text/xml");
1168
        out.println
1169
        ("<error>Configuration not allow to replicate document to you</error>");
1170
        out.close();
1171
        return;
1172
      }//if
1173

    
1174
      // Store the sql command
1175
      StringBuffer docsql = new StringBuffer();
1176
      StringBuffer revisionSql = new StringBuffer();
1177
      // Stroe the docid list
1178
      StringBuffer doclist = new StringBuffer();
1179
      // Store the deleted docid list
1180
      StringBuffer delsql = new StringBuffer();
1181
      // Store the data set file
1182
      Vector packageFiles = new Vector();
1183

    
1184
      // Append local server's name and replication servlet to doclist
1185
      doclist.append("<?xml version=\"1.0\"?><replication>");
1186
      doclist.append("<server>").append(util.getLocalReplicationServerName());
1187
      //doclist.append(util.getOption("replicationpath"));
1188
      doclist.append("</server><updates>");
1189

    
1190
      // Get correct docid that reside on this server according the requesting
1191
      // server's replicate and data replicate value in xml_replication table
1192
      docsql.append(dbAdapter.getReplicationDocumentListSQL());
1193
      //docsql.append("select docid, rev, doctype from xml_documents where (docid not in (select a.docid from xml_documents a, xml_revisions b where a.docid=b.docid and a.rev<=b.rev)) ");
1194
      revisionSql.append("select docid, rev, doctype from xml_revisions ");
1195
      // If the localhost is not a hub to the remote server, only replicate
1196
      // the docid' which home server is local host (server_location =1)
1197
      if (!serverList.getHubValue(server))
1198
      {
1199
    	String serverLocationDoc = " and a.server_location = 1";
1200
        String serverLocationRev = "where server_location = 1";
1201
        docsql.append(serverLocationDoc);
1202
        revisionSql.append(serverLocationRev);
1203
      }
1204
      logMetacat.info("Doc sql: "+docsql.toString());
1205

    
1206
      // Get any deleted documents
1207
      delsql.append("select distinct docid from ");
1208
      delsql.append("xml_revisions where docid not in (select docid from ");
1209
      delsql.append("xml_documents) ");
1210
      // If the localhost is not a hub to the remote server, only replicate
1211
      // the docid' which home server is local host (server_location =1)
1212
      if (!serverList.getHubValue(server))
1213
      {
1214
        delsql.append("and server_location = 1");
1215
      }
1216
      logMetacat.info("Deleted sql: "+delsql.toString());
1217

    
1218

    
1219

    
1220
      // Get docid list of local host
1221
      pstmt = dbConn.prepareStatement(docsql.toString());
1222
      pstmt.execute();
1223
      ResultSet rs = pstmt.getResultSet();
1224
      boolean tablehasrows = rs.next();
1225
      //If metacat configed to replicate data file
1226
      //if ((util.getOption("replicationsenddata")).equals("on"))
1227
      boolean replicateData = serverList.getDataReplicationValue(server);
1228
      if (replicateData)
1229
      {
1230
        while(tablehasrows)
1231
        {
1232
          String recordDoctype = rs.getString(3);
1233
          Vector packagedoctypes = MetaCatUtil.getOptionList(
1234
                                     MetaCatUtil.getOption("packagedoctype"));
1235
          //if this is a package file, put it at the end
1236
          //because if a package file is read before all of the files it
1237
          //refers to are loaded then there is an error
1238
          if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1239
          {
1240
              //If this is not data file
1241
              if (!recordDoctype.equals("BIN"))
1242
              {
1243
                //for non-data file document
1244
                doclist.append("<updatedDocument>");
1245
                doclist.append("<docid>").append(rs.getString(1));
1246
                doclist.append("</docid><rev>").append(rs.getInt(2));
1247
                doclist.append("</rev>");
1248
                doclist.append("</updatedDocument>");
1249
              }//if
1250
              else
1251
              {
1252
                //for data file document, in datafile attributes
1253
                //we put "datafile" value there
1254
                doclist.append("<updatedDocument>");
1255
                doclist.append("<docid>").append(rs.getString(1));
1256
                doclist.append("</docid><rev>").append(rs.getInt(2));
1257
                doclist.append("</rev>");
1258
                doclist.append("<datafile>");
1259
                doclist.append(MetaCatUtil.getOption("datafileflag"));
1260
                doclist.append("</datafile>");
1261
                doclist.append("</updatedDocument>");
1262
              }//else
1263
          }//if packagedoctpes
1264
          else
1265
          { //the package files are saved to be put into the xml later.
1266
              Vector v = new Vector();
1267
              v.add(new String(rs.getString(1)));
1268
              v.add(new Integer(rs.getInt(2)));
1269
              packageFiles.add(new Vector(v));
1270
          }//esle
1271
          tablehasrows = rs.next();
1272
        }//while
1273
      }//if
1274
      else //metacat was configured not to send data file
1275
      {
1276
        while(tablehasrows)
1277
        {
1278
          String recordDoctype = rs.getString(3);
1279
          if(!recordDoctype.equals("BIN"))
1280
          { //don't replicate data files
1281
            Vector packagedoctypes = MetaCatUtil.getOptionList(
1282
                                     MetaCatUtil.getOption("packagedoctype"));
1283
            if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1284
            {   //if this is a package file, put it at the end
1285
              //because if a package file is read before all of the files it
1286
              //refers to are loaded then there is an error
1287
              doclist.append("<updatedDocument>");
1288
              doclist.append("<docid>").append(rs.getString(1));
1289
              doclist.append("</docid><rev>").append(rs.getInt(2));
1290
              doclist.append("</rev>");
1291
              doclist.append("</updatedDocument>");
1292
            }
1293
            else
1294
            { //the package files are saved to be put into the xml later.
1295
              Vector v = new Vector();
1296
              v.add(new String(rs.getString(1)));
1297
              v.add(new Integer(rs.getInt(2)));
1298
              packageFiles.add(new Vector(v));
1299
            }
1300
         }//if
1301
         tablehasrows = rs.next();
1302
        }//while
1303
      }//else
1304

    
1305
      pstmt = dbConn.prepareStatement(delsql.toString());
1306
      //usage count should increas 1
1307
      dbConn.increaseUsageCount(1);
1308

    
1309
      pstmt.execute();
1310
      rs = pstmt.getResultSet();
1311
      tablehasrows = rs.next();
1312
      while(tablehasrows)
1313
      { //handle the deleted documents
1314
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1315
        doclist.append("</docid><rev></rev></deletedDocument>");
1316
        //note that rev is always empty for deleted docs
1317
        tablehasrows = rs.next();
1318
      }
1319

    
1320
      //now we can put the package files into the xml results
1321
      for(int i=0; i<packageFiles.size(); i++)
1322
      {
1323
        Vector v = (Vector)packageFiles.elementAt(i);
1324
        doclist.append("<updatedDocument>");
1325
        doclist.append("<docid>").append((String)v.elementAt(0));
1326
        doclist.append("</docid><rev>");
1327
        doclist.append(((Integer)v.elementAt(1)).intValue());
1328
        doclist.append("</rev>");
1329
        doclist.append("</updatedDocument>");
1330
      }
1331
      // add revision doc list  
1332
      doclist.append(prepareRevisionDoc(dbConn,revisionSql.toString(),replicateData));
1333
        
1334
      doclist.append("</updates></replication>");
1335
      logMetacat.info("doclist: " + doclist.toString());
1336
      pstmt.close();
1337
      //conn.close();
1338
      response.setContentType("text/xml");
1339
      out.println(doclist.toString());
1340

    
1341
    }
1342
    catch(Exception e)
1343
    {
1344
      logMetacat.error("error in MetacatReplication." +
1345
                         "handleupdaterequest: " + e.getMessage());
1346
      //e.printStackTrace(System.out);
1347
      response.setContentType("text/xml");
1348
      out.println("<error>"+e.getMessage()+"</error>");
1349
    }
1350
    finally
1351
    {
1352
      try
1353
      {
1354
        pstmt.close();
1355
      }//try
1356
      catch (SQLException ee)
1357
      {
1358
        logMetacat.error("Error in MetacatReplication." +
1359
                "handleUpdaterequest to close pstmt: "+ee.getMessage());
1360
      }//catch
1361
      finally
1362
      {
1363
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1364
      }//finally
1365
    }//finally
1366

    
1367
  }//handlUpdateRequest
1368
  
1369
  /*
1370
   * This method will get the xml string for document in xml_revision
1371
   * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1372
   */
1373
  private String prepareRevisionDoc(DBConnection dbConn, String revSql, 
1374
                            boolean replicateData) throws Exception
1375
  {
1376
      logMetacat.warn("The revision document sql is "+ revSql);
1377
      StringBuffer revDocList = new StringBuffer();
1378
      PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1379
      //usage count should increas 1
1380
      dbConn.increaseUsageCount(1);
1381

    
1382
      pstmt.execute();
1383
      ResultSet rs = pstmt.getResultSet();
1384
      boolean tablehasrows = rs.next();
1385
      while(tablehasrows)
1386
      {
1387
        String recordDoctype = rs.getString(3);
1388
        
1389
        //If this is data file and it isn't configured to replicate data
1390
        if (recordDoctype.equals("BIN") && !replicateData)
1391
        {  
1392
            // do nothing
1393
            continue;
1394
        }
1395
        else
1396
        {  
1397
            
1398
            revDocList.append("<revisionDocument>");
1399
            revDocList.append("<docid>").append(rs.getString(1));
1400
            revDocList.append("</docid><rev>").append(rs.getInt(2));
1401
            revDocList.append("</rev>");
1402
            // data file
1403
            if (recordDoctype.equals("BIN"))
1404
            {
1405
                revDocList.append("<datafile>");
1406
                revDocList.append(MetaCatUtil.getOption("datafileflag"));
1407
                revDocList.append("</datafile>");
1408
            }
1409
            revDocList.append("</revisionDocument>");
1410
        
1411
         }//else
1412
         tablehasrows = rs.next();
1413
      }
1414
      //System.out.println("The revision list is"+ revDocList.toString());
1415
      return revDocList.toString();
1416
  }
1417

    
1418
  /**
1419
   * Returns the xml_catalog table encoded in xml
1420
   */
1421
  public static String getCatalogXML()
1422
  {
1423
    return handleGetCatalogRequest(null, null, null, false);
1424
  }
1425

    
1426
  /**
1427
   * Sends the contents of the xml_catalog table encoded in xml
1428
   * The xml format is:
1429
   * <!ELEMENT xml_catalog (row*)>
1430
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1431
   *                system_id)>
1432
   * All of the sub elements of row are #PCDATA
1433

    
1434
   * If printFlag == false then do not print to out.
1435
   */
1436
  private static String handleGetCatalogRequest(PrintWriter out,
1437
                                                Hashtable params,
1438
                                                HttpServletResponse response,
1439
                                                boolean printFlag)
1440
  {
1441
    DBConnection dbConn = null;
1442
    int serialNumber = -1;
1443
    PreparedStatement pstmt = null;
1444
    try
1445
    {
1446
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1447
                                                "handleGetCatalogRequest");*/
1448
      dbConn=DBConnectionPool.
1449
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1450
      serialNumber=dbConn.getCheckOutSerialNumber();
1451
      pstmt = dbConn.prepareStatement("select entry_type, " +
1452
                              "source_doctype, target_doctype, public_id, " +
1453
                              "system_id from xml_catalog");
1454
      pstmt.execute();
1455
      ResultSet rs = pstmt.getResultSet();
1456
      boolean tablehasrows = rs.next();
1457
      StringBuffer sb = new StringBuffer();
1458
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1459
      while(tablehasrows)
1460
      {
1461
        sb.append("<row><entry_type>").append(rs.getString(1));
1462
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1463
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1464
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1465
        sb.append("</public_id><system_id>").append(rs.getString(5));
1466
        sb.append("</system_id></row>");
1467

    
1468
        tablehasrows = rs.next();
1469
      }
1470
      sb.append("</xml_catalog>");
1471
      //conn.close();
1472
      if(printFlag)
1473
      {
1474
        response.setContentType("text/xml");
1475
        out.println(sb.toString());
1476
      }
1477
      pstmt.close();
1478
      return sb.toString();
1479
    }
1480
    catch(Exception e)
1481
    {
1482

    
1483
      logMetacat.error("error in MetacatReplication.handleGetCatalogRequest:"+
1484
                          e.getMessage());
1485
      e.printStackTrace(System.out);
1486
      if(printFlag)
1487
      {
1488
        out.println("<error>"+e.getMessage()+"</error>");
1489
      }
1490
    }
1491
    finally
1492
    {
1493
      try
1494
      {
1495
        pstmt.close();
1496
      }//try
1497
      catch (SQLException ee)
1498
      {
1499
        logMetacat.error("Error in MetacatReplication.handleGetCatalogRequest: "
1500
           +ee.getMessage());
1501
      }//catch
1502
      finally
1503
      {
1504
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1505
      }//finally
1506
    }//finally
1507

    
1508
    return null;
1509
  }
1510

    
1511
  /**
1512
   * Sends the current system date to the remote server.  Using this action
1513
   * for replication gets rid of any problems with syncronizing clocks
1514
   * because a time specific to a document is always kept on its home server.
1515
   */
1516
  private void handleGetTimeRequest(PrintWriter out, Hashtable params,
1517
                                    HttpServletResponse response)
1518
  {
1519
    SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yy HH:mm:ss");
1520
    java.util.Date localtime = new java.util.Date();
1521
    String dateString = formatter.format(localtime);
1522
    response.setContentType("text/xml");
1523

    
1524
    out.println("<timestamp>" + dateString + "</timestamp>");
1525
  }
1526

    
1527
  /**
1528
   * this method handles the timeout for a file lock.  when a lock is
1529
   * granted it is granted for 30 seconds.  When this thread runs out
1530
   * it deletes the docid from the queue, thus eliminating the lock.
1531
   */
1532
  public void run()
1533
  {
1534
    try
1535
    {
1536
      logMetacat.info("thread started for docid: " +
1537
                               (String)fileLocks.elementAt(0));
1538

    
1539
      Thread.sleep(30000); //the lock will expire in 30 seconds
1540
      logMetacat.info("thread for docid: " +
1541
                             (String)fileLocks.elementAt(fileLocks.size() - 1) +
1542
                              " exiting.");
1543

    
1544
      fileLocks.remove(fileLocks.size() - 1);
1545
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1546
      //in the vector, the first one inserted will be removed.
1547
    }
1548
    catch(Exception e)
1549
    {
1550
      logMetacat.error("error in file lock thread from " +
1551
                                "MetacatReplication.run: " + e.getMessage());
1552
    }
1553
  }
1554

    
1555
  /**
1556
   * Returns the name of a server given a serverCode
1557
   * @param serverCode the serverid of the server
1558
   * @return the servername or null if the specified serverCode does not
1559
   *         exist.
1560
   */
1561
  public static String getServerNameForServerCode(int serverCode)
1562
  {
1563
    //System.out.println("serverid: " + serverCode);
1564
    DBConnection dbConn = null;
1565
    int serialNumber = -1;
1566
    PreparedStatement pstmt = null;
1567
    try
1568
    {
1569
      dbConn=DBConnectionPool.
1570
                  getDBConnection("MetacatReplication.getServer");
1571
      serialNumber=dbConn.getCheckOutSerialNumber();
1572
      String sql = new String("select server from " +
1573
                              "xml_replication where serverid = " +
1574
                              serverCode);
1575
      pstmt = dbConn.prepareStatement(sql);
1576
      //System.out.println("getserver sql: " + sql);
1577
      pstmt.execute();
1578
      ResultSet rs = pstmt.getResultSet();
1579
      boolean tablehasrows = rs.next();
1580
      if(tablehasrows)
1581
      {
1582
        //System.out.println("server: " + rs.getString(1));
1583
        return rs.getString(1);
1584
      }
1585

    
1586
      //conn.close();
1587
    }
1588
    catch(Exception e)
1589
    {
1590
      System.out.println("Error in MetacatReplication.getServer: " +
1591
                          e.getMessage());
1592
    }
1593
    finally
1594
    {
1595
      try
1596
      {
1597
        pstmt.close();
1598
      }//try
1599
      catch (SQLException ee)
1600
      {
1601
        logMetacat.error("Error in MetacactReplication.getserver: "+
1602
                                    ee.getMessage());
1603
      }//catch
1604
      finally
1605
      {
1606
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1607
      }//fianlly
1608
    }//finally
1609

    
1610

    
1611

    
1612
    return null;
1613
      //return null if the server does not exist
1614
  }
1615

    
1616
  /**
1617
   * Returns a server code given a server name
1618
   * @param server the name of the server
1619
   * @return integer > 0 representing the code of the server, 0 if the server
1620
   *  does not exist.
1621
   */
1622
  public static int getServerCodeForServerName(String server) throws Exception
1623
  {
1624
    DBConnection dbConn = null;
1625
    int serialNumber = -1;
1626
    PreparedStatement pstmt = null;
1627
    int serverCode = 0;
1628

    
1629
    try {
1630

    
1631
      //conn = util.openDBConnection();
1632
      dbConn=DBConnectionPool.
1633
                  getDBConnection("MetacatReplication.getServerCode");
1634
      serialNumber=dbConn.getCheckOutSerialNumber();
1635
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1636
                                    "WHERE server LIKE '" + server + "'");
1637
      pstmt.execute();
1638
      ResultSet rs = pstmt.getResultSet();
1639
      boolean tablehasrows = rs.next();
1640
      if ( tablehasrows ) {
1641
        serverCode = rs.getInt(1);
1642
        pstmt.close();
1643
        //conn.close();
1644
        return serverCode;
1645
      }
1646

    
1647
    } catch(Exception e) {
1648
      throw e;
1649

    
1650
    } finally {
1651
      try
1652
      {
1653
        pstmt.close();
1654
        //conn.close();
1655
       }//try
1656
       catch(Exception ee)
1657
       {
1658
         logMetacat.error("Error in MetacatReplicatio.getServerCode: "
1659
                                  +ee.getMessage());
1660

    
1661
       }//catch
1662
       finally
1663
       {
1664
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1665
       }//finally
1666
    }//finally
1667

    
1668
    return serverCode;
1669
  }
1670

    
1671
  /**
1672
   * Method to get a host server information for given docid
1673
   * @param conn a connection to the database
1674
   */
1675
  public static Hashtable getHomeServerInfoForDocId(String docId)
1676
  {
1677
    Hashtable sl = new Hashtable();
1678
    DBConnection dbConn = null;
1679
    int serialNumber = -1;
1680
    //MetaCatUtil ut=new MetaCatUtil();
1681
    docId=MetaCatUtil.getDocIdFromString(docId);
1682
    PreparedStatement pstmt=null;
1683
    int serverLocation;
1684
    try
1685
    {
1686
      //get conection
1687
      dbConn=DBConnectionPool.
1688
                  getDBConnection("ReplicationHandler.getHomeServer");
1689
      serialNumber=dbConn.getCheckOutSerialNumber();
1690
      //get a server location from xml_document table
1691
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
1692
                                            +"where docid = ?");
1693
      pstmt.setString(1, docId);
1694
      pstmt.execute();
1695
      ResultSet serverName = pstmt.getResultSet();
1696
      //get a server location
1697
      if(serverName.next())
1698
      {
1699
        serverLocation=serverName.getInt(1);
1700
        pstmt.close();
1701
      }
1702
      else
1703
      {
1704
        pstmt.close();
1705
        //ut.returnConnection(conn);
1706
        return null;
1707
      }
1708
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
1709
                        "from xml_replication where serverid = ?");
1710
      //increase usage count
1711
      dbConn.increaseUsageCount(1);
1712
      pstmt.setInt(1, serverLocation);
1713
      pstmt.execute();
1714
      ResultSet rs = pstmt.getResultSet();
1715
      boolean tableHasRows = rs.next();
1716
      if (tableHasRows)
1717
      {
1718

    
1719
          String server = rs.getString(1);
1720
          String last_checked = rs.getString(2);
1721
          if(!server.equals("localhost"))
1722
          {
1723
            sl.put(server, last_checked);
1724
          }
1725

    
1726
      }
1727
      else
1728
      {
1729
        pstmt.close();
1730
        //ut.returnConnection(conn);
1731
        return null;
1732
      }
1733
      pstmt.close();
1734
    }
1735
    catch(Exception e)
1736
    {
1737
      System.out.println("error in replicationHandler.getHomeServer(): " +
1738
                         e.getMessage());
1739
    }
1740
    finally
1741
    {
1742
      try
1743
      {
1744
        pstmt.close();
1745
        //ut.returnConnection(conn);
1746
      }
1747
      catch (Exception ee)
1748
      {
1749
        logMetacat.error("Eror irn rplicationHandler.getHomeServer() "+
1750
                          "to close pstmt: "+ee.getMessage());
1751
      }
1752
      finally
1753
      {
1754
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1755
      }
1756

    
1757
    }//finally
1758
    return sl;
1759
  }
1760

    
1761
  /**
1762
   * Returns a home server location  given a accnum
1763
   * @param accNum , given accNum for a document
1764
   *
1765
   */
1766
  public static int getHomeServerCodeForDocId(String accNum) throws Exception
1767
  {
1768
    DBConnection dbConn = null;
1769
    int serialNumber = -1;
1770
    PreparedStatement pstmt = null;
1771
    int serverCode = 1;
1772
    //MetaCatUtil ut = new MetaCatUtil();
1773
    String docId=MetaCatUtil.getDocIdFromString(accNum);
1774

    
1775
    try
1776
    {
1777

    
1778
      // Get DBConnection
1779
      dbConn=DBConnectionPool.
1780
                  getDBConnection("ReplicationHandler.getServerLocation");
1781
      serialNumber=dbConn.getCheckOutSerialNumber();
1782
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1783
                              + "WHERE docid LIKE '" + docId + "'");
1784
      pstmt.execute();
1785
      ResultSet rs = pstmt.getResultSet();
1786
      boolean tablehasrows = rs.next();
1787
      //If a document is find, return the server location for it
1788
      if ( tablehasrows )
1789
      {
1790
        serverCode = rs.getInt(1);
1791
        pstmt.close();
1792
        //conn.close();
1793
        return serverCode;
1794
      }
1795
      //if couldn't find in xml_documents table, we think server code is 1
1796
      //(this is new document)
1797
      else
1798
      {
1799
        pstmt.close();
1800
        //conn.close();
1801
        return serverCode;
1802
      }
1803

    
1804
    }
1805
    catch(Exception e)
1806
    {
1807

    
1808
      throw e;
1809

    
1810
    }
1811
    finally
1812
    {
1813
      try
1814
      {
1815
        pstmt.close();
1816
        //conn.close();
1817

    
1818
      }
1819
      catch(Exception ee)
1820
      {
1821
        logMetacat.error("Erorr in Replication.getServerLocation "+
1822
                     "to close pstmt"+ee.getMessage());
1823
      }
1824
      finally
1825
      {
1826
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1827
      }//finally
1828
    }//finally
1829
   //return serverCode;
1830
  }
1831

    
1832

    
1833

    
1834
  /**
1835
   * This method returns the content of a url
1836
   * @param u the url to return the content from
1837
   * @return a string representing the content of the url
1838
   * @throws java.io.IOException
1839
   */
1840
  public static String getURLContent(URL u) throws java.io.IOException
1841
  {
1842
    char istreamChar;
1843
    int istreamInt;
1844
    logMetacat.info("Before open the stream"+u.toString());
1845
    InputStream input = u.openStream();
1846
    logMetacat.info("Afetr open the stream"+u.toString());
1847
    InputStreamReader istream = new InputStreamReader(input);
1848
    StringBuffer serverResponse = new StringBuffer();
1849
    while((istreamInt = istream.read()) != -1)
1850
    {
1851
      istreamChar = (char)istreamInt;
1852
      serverResponse.append(istreamChar);
1853
    }
1854
    istream.close();
1855
    input.close();
1856

    
1857
    return serverResponse.toString();
1858
  }
1859

    
1860
  /**
1861
   * Method for writing replication messages to a log file specified in
1862
   * metacat.properties
1863
   */
1864
  public static void replLog(String message)
1865
  {
1866
    try
1867
    {
1868
      FileOutputStream fos = new FileOutputStream(
1869
                                 util.getOption("replicationlog"), true);
1870
      PrintWriter pw = new PrintWriter(fos);
1871
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1872
      java.util.Date localtime = new java.util.Date();
1873
      String dateString = formatter.format(localtime);
1874
      dateString += " :: " + message;
1875
      //time stamp each entry
1876
      pw.println(dateString);
1877
      pw.flush();
1878
    }
1879
    catch(Exception e)
1880
    {
1881
      System.out.println("error writing to replication log from " +
1882
                         "MetacatReplication.replLog: " + e.getMessage());
1883
      //e.printStackTrace(System.out);
1884
    }
1885
  }
1886

    
1887
  /**
1888
   * Method for writing replication messages to a log file specified in
1889
   * metacat.properties
1890
   */
1891
  public static void replErrorLog(String message)
1892
  {
1893
    try
1894
    {
1895
      FileOutputStream fos = new FileOutputStream(
1896
                                 util.getOption("replicationerrorlog"), true);
1897
      PrintWriter pw = new PrintWriter(fos);
1898
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1899
      java.util.Date localtime = new java.util.Date();
1900
      String dateString = formatter.format(localtime);
1901
      dateString += " :: " + message;
1902
      //time stamp each entry
1903
      pw.println(dateString);
1904
      pw.flush();
1905
    }
1906
    catch(Exception e)
1907
    {
1908
      System.out.println("error writing to replication log from " +
1909
                         "MetacatReplication.replLog: " + e.getMessage());
1910
      //e.printStackTrace(System.out);
1911
    }
1912
  }
1913

    
1914
  /**
1915
   * Returns true if the replicate field for server in xml_replication is 1.
1916
   * Returns false otherwise
1917
   */
1918
  public static boolean replToServer(String server)
1919
  {
1920
    DBConnection dbConn = null;
1921
    int serialNumber = -1;
1922
    PreparedStatement pstmt = null;
1923
    try
1924
    {
1925
      dbConn=DBConnectionPool.
1926
                  getDBConnection("MetacatReplication.repltoServer");
1927
      serialNumber=dbConn.getCheckOutSerialNumber();
1928
      pstmt = dbConn.prepareStatement("select replicate from " +
1929
                                    "xml_replication where server like '" +
1930
                                     server + "'");
1931
      pstmt.execute();
1932
      ResultSet rs = pstmt.getResultSet();
1933
      boolean tablehasrows = rs.next();
1934
      if(tablehasrows)
1935
      {
1936
        int i = rs.getInt(1);
1937
        if(i == 1)
1938
        {
1939
          pstmt.close();
1940
          //conn.close();
1941
          return true;
1942
        }
1943
        else
1944
        {
1945
          pstmt.close();
1946
          //conn.close();
1947
          return false;
1948
        }
1949
      }
1950
    }
1951
    catch(Exception e)
1952
    {
1953
      System.out.println("error in MetacatReplication.replToServer: " +
1954
                         e.getMessage());
1955
    }
1956
    finally
1957
    {
1958
      try
1959
      {
1960
        pstmt.close();
1961
        //conn.close();
1962
      }//try
1963
      catch(Exception ee)
1964
      {
1965
        logMetacat.error("Error in MetacatReplication.replToServer: "
1966
                                  +ee.getMessage());
1967
      }//catch
1968
      finally
1969
      {
1970
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1971
      }//finally
1972
    }//finally
1973
    return false;
1974
    //the default if this server does not exist is to not replicate to it.
1975
  }
1976

    
1977

    
1978
}
(46-46/66)