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
 *    Release: @release@
8
 *
9
 *   '$Author: tao $'
10
 *     '$Date: 2002-06-13 11:54:51 -0700 (Thu, 13 Jun 2002) $'
11
 * '$Revision: 1217 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

    
30
import java.util.*;
31
import java.io.*;
32
import java.sql.*;
33
import java.net.*;
34
import java.lang.*;
35
import java.text.*;
36
import javax.servlet.*;
37
import javax.servlet.http.*;
38

    
39
import org.xml.sax.*;
40

    
41
public class MetacatReplication extends HttpServlet implements Runnable
42
{  
43
  private String deltaT;
44
  Timer replicationDaemon;
45
  private static MetaCatUtil util = new MetaCatUtil();
46
  private Vector fileLocks = new Vector();
47
  private Thread lockThread = null;
48
  
49
  /**
50
   * Initialize the servlet by creating appropriate database connections
51
   */
52
  public void init(ServletConfig config) throws ServletException 
53
  {
54
    //initialize db connections to handle any update requests
55
    MetaCatUtil util = new MetaCatUtil();
56
    deltaT = util.getOption("deltaT");
57
    //the default deltaT can be set from metacat.properties
58
    //create a thread to do the delta-T check but don't execute it yet
59
    replicationDaemon = new Timer(true);
60
  }
61
  
62
  public void destroy() 
63
  {
64
    replicationDaemon.cancel();
65
   // System.out.println("Replication daemon cancelled.");
66
  }
67
  
68
  public void doGet (HttpServletRequest request, HttpServletResponse response)
69
                     throws ServletException, IOException 
70
  {
71
    // Process the data and send back the response
72
    handleGetOrPost(request, response);
73
  }
74

    
75
  public void doPost(HttpServletRequest request, HttpServletResponse response)
76
                     throws ServletException, IOException 
77
  {
78
    // Process the data and send back the response
79
    handleGetOrPost(request, response);
80
  }
81
  
82
  private void handleGetOrPost(HttpServletRequest request, 
83
                               HttpServletResponse response) 
84
                               throws ServletException, IOException 
85
  {
86
    //PrintWriter out = response.getWriter();
87
    //ServletOutputStream outPut = response.getOutputStream();
88
    Hashtable params = new Hashtable();
89
    Enumeration paramlist = request.getParameterNames();
90
    
91
    //First check if administrate conifgure the replcation feature on
92
    //This configuration is set in build.xml file
93
    //If it is not on, reject any request.
94
    if (!(util.getOption("replication")).equals("on"))
95
    {
96
     (response.getWriter()).println("MetaCat is not set to handle replication");
97
      (response.getWriter()).close();
98
      return;
99
    }
100
    
101
// NOT NEEDED - doesn't provide enough security because of possible IP spoofing
102
// REPLACED with running replication comminications over HTTPS
103
//    String requestingServerIP = request.getRemoteAddr();
104
//    InetAddress iaddr = InetAddress.getByName(requestingServerIP);
105
//    String requestingServer = iaddr.getHostName();
106
    
107
    while (paramlist.hasMoreElements()) {
108
      String name = (String)paramlist.nextElement();
109
      String[] value = request.getParameterValues(name);
110
      params.put(name, value);  
111
    }
112
    
113
    String action = ((String[])params.get("action"))[0];
114
    String server = null;
115
    
116
    try {
117
      // check if the server is included in the list of replicated servers
118
      if ( !action.equals("servercontrol") && 
119
           !action.equals("stop") &&
120
           !action.equals("start") &&
121
           !action.equals("getall") ) {
122

    
123
        server = ((String[])params.get("server"))[0];
124
        if ( getServerCode(server) == 0 ) {
125
          System.out.println("Action \"" + action + 
126
                             "\" rejected for server: " + server);
127
          return;
128
        } else {
129
          System.out.println("Action \"" + action + 
130
                             "\" accepted for server: " + server);
131
        }
132
      }
133
    } catch (Exception e) {
134
      System.out.println("Error in MetacatReplication.handleGetOrPost: " +
135
                         e.getMessage() );
136
      return;
137
    }
138
    if ( action.equals("readdata") ) 
139
    {
140
      OutputStream out=response.getOutputStream();
141
      //to get the data file.
142
      handleGetDataFileRequest(out, params, response);
143
      out.close();
144
    }
145
    else if ( action.equals("forcereplicatedatafile") ) 
146
    {
147
     
148
      //OutputStream out=response.getOutputStream();
149
      //read a specific docid from remote host, and store it into local host
150
      handleForceReplicateDataFileRequest(params);
151
      //out.close();
152
    }
153
    else
154
    {
155
    PrintWriter out = response.getWriter();
156
    if ( action.equals("stop") ) {
157
      //stop the replication server
158
      replicationDaemon.cancel();
159
      replicationDaemon = new Timer(true);
160
      out.println("Replication Handler Stopped");
161
      MetacatReplication.replLog("deltaT handler stopped");
162
    
163

    
164
    } else if ( action.equals("start") ) {
165
      
166
      //start the replication server
167
      int rate;
168
      if ( params.containsKey("rate") ) {
169
        rate = new Integer(
170
               new String(((String[])params.get("rate"))[0])).intValue();
171
        if(rate < 30) {
172
            out.println("Replication deltaT rate cannot be less than 30!");
173
            //deltaT<30 is a timing mess!
174
            rate = 1000;
175
        }
176
      } else {
177
        rate = 1000;
178
      }
179
      out.println("New rate is: " + rate + " seconds.");
180
      replicationDaemon.cancel();
181
      replicationDaemon = new Timer(true);
182
      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(out), 0, 
183
                                            rate * 1000);
184
      out.println("Replication Handler Started");
185
      MetacatReplication.replLog("deltaT handler started with rate=" + 
186
                                    rate + " seconds");
187
     
188

    
189
    } else if ( action.equals("getall") ) {
190
      //updates this server exactly once
191
      replicationDaemon.schedule(new ReplicationHandler(out), 0);
192
      response.setContentType("text/html");
193
      out.println("<html><body>\"Get All\" Done</body></html>");
194

    
195
    } else if ( action.equals("forcereplicate") ) {
196
      //read a specific docid from remote host, and store it into local host
197
      handleForceReplicateRequest(out, params, response);
198
   
199
    } else if ( action.equals("update") ) {
200
      //request an update list from the server
201
      handleUpdateRequest(out, params, response);
202

    
203
    } else if ( action.equals("read") ) {
204
      //request a specific document from the server
205
      //note that this could be replaced by a call to metacatServlet
206
      //handleGetDocumentAction().
207
      handleGetDocumentRequest(out, params, response);
208
    } else if ( action.equals("getlock") ) {
209
      handleGetLockRequest(out, params, response);
210

    
211
    } else if ( action.equals("getdocumentinfo") ) {
212
      handleGetDocumentInfoRequest(out, params, response);
213

    
214
    } else if ( action.equals("gettime") ) {
215
      handleGetTimeRequest(out, params, response);
216

    
217
    } else if ( action.equals("getcatalog") ) {
218
      handleGetCatalogRequest(out, params, response, true);
219

    
220
    } else if ( action.equals("servercontrol") ) {
221
      handleServerControlRequest(out, params, response);
222
    } else if ( action.equals("test") ) {
223
      response.setContentType("text/html");
224
      out.println("<html><body>Test successfully</body></html>");
225
    }
226
    
227
    out.close();
228
    }//else
229
  }
230
  
231
  /** 
232
   * This method can add, delete and list the servers currently included in
233
   * xml_replication.
234
   * action           subaction            other needed params
235
   * ---------------------------------------------------------
236
   * servercontrol    add                  server
237
   * servercontrol    delete               server
238
   * servercontrol    list                 
239
   */
240
  private void handleServerControlRequest(PrintWriter out, Hashtable params,
241
                                          HttpServletResponse response)
242
  {
243
    String subaction = ((String[])params.get("subaction"))[0];
244
    DBConnection dbConn = null;
245
    int serialNumber = -1;
246
    PreparedStatement pstmt = null;
247

    
248
    try {
249
      //conn = util.openDBConnection();
250
      dbConn=DBConnectionPool.
251
               getDBConnection("MetacatReplication.handleServerControlRequest");
252
      serialNumber=dbConn.getCheckOutSerialNumber();
253
      
254
      // add server to server list
255
      if ( subaction.equals("add") ) {
256
        String replicate = ((String[])params.get("replicate"))[0];
257
        String server = ((String[])params.get("server"))[0];
258
        pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
259
                                      "(server, last_checked, replicate) " +
260
                                      "VALUES ('" + server + "', to_date(" +
261
                                      "'01/01/00', 'MM/DD/YY'), '" +
262
                                      replicate + "')");
263
        pstmt.execute();
264
        pstmt.close();
265
        dbConn.commit();
266
        out.println("Server " + server + " added"); 
267
        response.setContentType("text/html");
268
        out.println("<html><body><table border=\"1\">");
269
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
270
        out.println("<b>replicate</b></td></tr>");
271
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
272
        //increase dbconnection usage
273
        dbConn.increaseUsageCount(1);
274
        
275
        pstmt.execute();
276
        ResultSet rs = pstmt.getResultSet();
277
        boolean tablehasrows = rs.next();
278
        while(tablehasrows) {
279
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
280
          out.println(rs.getString(3) + "</td><td>");
281
          out.println(rs.getString(4) + "</td></tr>");
282
          tablehasrows = rs.next();
283
        }
284
        out.println("</table></body></html>");
285
        
286
        // download certificate with the public key on this server
287
        // and import it as a trusted certificate
288
        String certURL = ((String[])params.get("certificate"))[0];
289
        downloadCertificate(certURL);
290
        
291
      // delete server from server list
292
      } else if ( subaction.equals("delete") ) {
293
        String server = ((String[])params.get("server"))[0];
294
        pstmt = dbConn.prepareStatement("DELETE FROM xml_replication " +
295
                                      "WHERE server LIKE '" + server + "'");
296
        pstmt.execute();
297
        pstmt.close();
298
        dbConn.commit();
299
        out.println("Server " + server + " deleted");
300
        response.setContentType("text/html");
301
        out.println("<html><body><table border=\"1\">");
302
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
303
        out.println("<b>replicate</b></td></tr>");
304
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
305
        //increase dbconnection usage
306
        dbConn.increaseUsageCount(1);
307
        pstmt.execute();
308
        ResultSet rs = pstmt.getResultSet();
309
        boolean tablehasrows = rs.next();
310
        while(tablehasrows)
311
        {
312
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
313
          out.println(rs.getString(3) + "</td><td>");
314
          out.println(rs.getString(4) + "</td></tr>");
315
          tablehasrows = rs.next();
316
        }
317
        out.println("</table></body></html>");
318

    
319
      // list servers in server list
320
      } else if ( subaction.equals("list") ) {
321
        response.setContentType("text/html");
322
        out.println("<html><body><table border=\"1\">");
323
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
324
        out.println("<b>replicate</b></td></tr>");
325
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
326
        pstmt.execute();
327
        ResultSet rs = pstmt.getResultSet();
328
        boolean tablehasrows = rs.next();
329
        while(tablehasrows) {
330
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
331
          out.println(rs.getString(3) + "</td><td>");
332
          out.println(rs.getString(4) + "</td></tr>");
333
          tablehasrows = rs.next();
334
        }
335
        out.println("</table></body></html>");
336
      }
337
      pstmt.close();
338
      //conn.close();
339

    
340
    } catch(Exception e) {
341
      System.out.println("Error in " + 
342
                         "MetacatReplication.handleServerControlRequest " + 
343
                         e.getMessage());
344
      e.printStackTrace(System.out);
345
    }
346
    finally
347
    {
348
      try
349
      {
350
        pstmt.close();
351
      }//try
352
      catch (SQLException ee)
353
      {
354
        MetaCatUtil.debugMessage("Error in " + 
355
                "MetacatReplication.handleServerControlRequest to close pstmt "
356
                 + ee.getMessage());
357
      }//catch
358
      finally
359
      {
360
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
361
      }//finally
362
    }//finally
363
      
364
  }
365
  
366
  // download certificate with the public key from certURL and 
367
  // upload it onto this server; it then must be imported as a 
368
  // trusted certificate 
369
  private void downloadCertificate (String certURL)
370
                throws FileNotFoundException, IOException, MalformedURLException
371
  {
372
    MetaCatUtil util = new MetaCatUtil();
373
    String certPath = util.getOption("certPath"); //the path to be uploaded to
374
    
375
    // get filename from the URL of the certificate
376
    String filename = certURL;
377
    int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
378
    if ( slash > -1 ) {
379
      filename = filename.substring(slash + 1);
380
    }
381
    
382
    // open file output strem to write the input into it
383
    File f = new File(certPath, filename);
384
    synchronized (f) { 
385
      try {
386
        if ( f.exists() ) {
387
          throw new IOException("File already exist: " + f.getCanonicalFile());
388
          //if ( f.exists() && !f.canWrite() ) {
389
          //  throw new IOException("Not writable: " + f.getCanonicalFile());
390
        }
391
      } catch (SecurityException se) {
392
        // if a security manager exists,
393
        // its checkRead method is called for f.exist()
394
        // or checkWrite method is called for f.canWrite()
395
        throw se;
396
      }
397
      
398
      // create a buffered byte output stream
399
      // that uses a default-sized output buffer
400
      FileOutputStream fos = new FileOutputStream(f);
401
      BufferedOutputStream out = new BufferedOutputStream(fos);
402

    
403
      // this should be http url
404
      URL url = new URL(certURL);
405
      BufferedInputStream bis = null;
406
      try {
407
        bis = new BufferedInputStream(url.openStream());
408
        byte[] buf = new byte[4 * 1024]; // 4K buffer
409
        int b = bis.read(buf);
410
        while (b != -1) {
411
          out.write(buf, 0, b);
412
          b = bis.read(buf);
413
        }
414
      } finally {
415
        if (bis != null) bis.close();
416
      }
417
      // the input and the output streams must be closed
418
      bis.close();
419
	    out.flush();
420
	    out.close();
421
	    fos.close();
422
    } // end of synchronized(f)
423
  }
424
  
425
  /**
426
   * when a forcereplication request comes in, local host sends a read request
427
   * to the requesting server (remote server) for the specified docid.
428
   * Then store it in local database.
429
   */
430
  private void handleForceReplicateRequest(PrintWriter out, Hashtable params,
431
                                           HttpServletResponse response)
432
  {
433
    String server = ((String[])params.get("server"))[0]; // the server that
434
    String docid = ((String[])params.get("docid"))[0]; // sent the document
435
    String dbaction = "UPDATE"; // the default action is UPDATE
436
    boolean override = false;
437
    int serverCode = 1;
438
    DBConnection dbConn = null;
439
    int serialNumber = -1;
440
   
441
    try {
442
      //if the url contains a dbaction then the default action is overridden
443
      if(params.containsKey("dbaction")) {
444
        dbaction = ((String[])params.get("dbaction"))[0];
445
        //serverCode = MetacatReplication.getServerCode(server);
446
        //override = true; //we are now overriding the default action
447
      }
448
      MetacatReplication.replLog("force replication request from " + server); 
449
      util.debugMessage("Force replication docid: "+docid, 20);
450
      util.debugMessage("Force replication action: "+dbaction, 20);
451
      // sending back read request to server
452
     
453
      URL u = new URL("https://" + server + "?server="
454
                +util.getLocalReplicationServerName()
455
                +"&action=read&docid=" + docid);
456
      String xmldoc = MetacatReplication.getURLContent(u);
457
    
458
      // get the document info from server
459
      URL docinfourl = new URL("https://" + server + 
460
                               "?server="+util.getLocalReplicationServerName()
461
                               +"&action=getdocumentinfo&docid=" + docid);
462
    
463
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
464
  
465
      //dih is the parser for the docinfo xml format
466
      DocInfoHandler dih = new DocInfoHandler();
467
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
468
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
469
      Hashtable docinfoHash = dih.getDocInfo();
470
      String user = (String)docinfoHash.get("user_owner");
471
      
472
      String homeServer=(String)docinfoHash.get("home_server");
473
      util.debugMessage("homeServer: "+homeServer,20);
474
      // write the document here
475
      //Connection conn = util.openDBConnection();
476
      dbConn=DBConnectionPool.
477
              getDBConnection("MetacatReplication.handleForceReplicateRequest");
478
      serialNumber=dbConn.getCheckOutSerialNumber();
479
      DocumentImpl.writeReplication(dbConn, 
480
                  new StringReader(xmldoc), null, null, dbaction, docid, user, 
481
                  null, homeServer, false);
482
              
483
       
484
      //conn.close();
485

    
486
      MetacatReplication.replLog("document " + docid + " added to DB with " +
487
                                 "action " + dbaction);
488
    } catch(Exception e) {
489
      
490
      System.out.println("ERROR in MetacatReplication.handleForceReplicate" +
491
                         "Request(): " + e.getMessage());
492
       e.printStackTrace();
493
    }
494
    finally
495
    {
496
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
497
    }//finally
498
  }
499
  
500
  /**
501
   * when a forcereplication data file request comes in, local host sends a 
502
   * readdata request to the requesting server (remote server) for the specified 
503
   * docid. Then store it in local database and file system
504
   */
505
  private void handleForceReplicateDataFileRequest(Hashtable params)
506
  {
507
    //check if the metacat was configured to handle replication 
508
    if (!(util.getOption("replicationacceptdata")).equals("on"))
509
    {
510
      return;
511
    }
512
    //make sure there is some parameters
513
    if(params.isEmpty())
514
    {
515
      return;
516
    }
517
    String server = ((String[])params.get("server"))[0]; // the server that
518
    //docid should include rev number
519
    String docid = ((String[])params.get("docid"))[0]; // sent the document
520
    if (docid==null)
521
    {
522
      util.debugMessage("Didn't specify docid for replication", 20);
523
      return;
524
    }
525
    //docid was switch to two parts
526
    boolean override = false;
527
    int serverCode = 1;
528
    String dbaction=null;
529
    //Connection conn=null;
530
    
531
    try 
532
    {
533
      //docid was switch to two parts
534
      String uniqueCode=MetaCatUtil.getDocIdFromString(docid);
535
      int rev=MetaCatUtil.getVersionFromString(docid);
536
      if(params.containsKey("dbaction")) 
537
      {
538
        dbaction = ((String[])params.get("dbaction"))[0];
539
      }
540
      else//default value is update
541
      {
542
        dbaction = "update";
543
      }
544
      //serverCode = MetacatReplication.getServerCode(server);
545
      MetacatReplication.replLog("force replication request from " + server); 
546
      
547
      // get the document info from server
548
      URL docinfourl = new URL("https://" + server + 
549
                               "?server="+util.getLocalReplicationServerName()
550
                               +"&action=getdocumentinfo&docid=" + uniqueCode);
551
     
552
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
553

    
554
      //dih is the parser for the docinfo xml format
555
      DocInfoHandler dih = new DocInfoHandler();
556
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
557
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
558
      Hashtable docinfoHash = dih.getDocInfo();
559
      String user = (String)docinfoHash.get("user_owner");
560
     
561
      String docName = (String)docinfoHash.get("docname");
562
     
563
      String docType = (String)docinfoHash.get("doctype");
564
      
565
      String docHomeServer= (String)docinfoHash.get("home_server");
566
      MetaCatUtil.debugMessage("docHomeServer of data file: "+docHomeServer);
567
      
568
      
569
      
570
      //if action is delete, we don't delete the data file. Just archieve
571
      //the xml_documents
572
      if (dbaction.equals("delete"))
573
      {
574
        //conn = util.getConnection();
575
        DocumentImpl.delete(docid,user,null);
576
        //util.returnConnection(conn);
577
      }
578
      //To data file insert or update is same
579
      else if (dbaction.equals("insert")||dbaction.equals("update"))
580
      {
581
        //Get data file and store it into local file system.
582
        // sending back readdata request to server
583
        URL url = new URL("https://" + server + "?server="
584
                +util.getLocalReplicationServerName()
585
                +"&action=readdata&docid=" + docid);
586
        String datafilePath = util.getOption("datafilepath");
587
        //register data file into xml_documents table and wite data file
588
        //into file system
589
        DocumentImpl.writeDataFile(url.openStream(), datafilePath, docName,
590
                              docType, docid, user,docHomeServer);
591
     }
592
    
593
  
594
    
595
    MetacatReplication.replLog("document " + docid + " added to DB with " +
596
                                 "action " + dbaction);
597
    } catch(Exception e) 
598
    {
599
      
600
      //util.returnConnection(conn);
601
      util.debugMessage("ERROR in MetacatReplication.handleForceReplicate" +
602
                         "Request(): " + e.getMessage(), 30);
603
    }
604
  }
605
  /**
606
   * Grants or denies a lock to a requesting host.
607
   * The servlet parameters of interrest are:
608
   * docid: the docid of the file the lock is being requested for
609
   * currentdate: the timestamp of the document on the remote server
610
   * 
611
   */
612
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
613
                                    HttpServletResponse response)
614
  {
615
    //Connection conn = null;
616
    try
617
    {
618
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
619
                                                "handleGetLockRequest");*/
620
      String docid = ((String[])params.get("docid"))[0];
621
      String remoteRev = ((String[])params.get("updaterev"))[0];
622
      DocumentImpl requestDoc = new DocumentImpl(docid);
623
      MetacatReplication.replLog("lock request for " + docid);
624
      int localRevInt = requestDoc.getRev();
625
      int remoteRevInt = Integer.parseInt(remoteRev);
626
      
627
      if(remoteRevInt >= localRevInt)
628
      {
629
        if(!fileLocks.contains(docid))
630
        { //grant the lock if it is not already locked
631
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
632
          //send a message back to the the remote host authorizing the insert
633
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
634
          lockThread = new Thread(this);
635
          lockThread.setPriority(Thread.MIN_PRIORITY);
636
          lockThread.start();
637
          MetacatReplication.replLog("lock granted for " + docid);
638
        }
639
        else
640
        { //deny the lock
641
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
642
          MetacatReplication.replLog("lock denied for " + docid + 
643
                                     "reason: file already locked");
644
        }
645
      }
646
      else
647
      {//deny the lock.
648
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
649
        MetacatReplication.replLog("lock denied for " + docid + 
650
                                   "reason: client has outdated file");
651
      }
652
      //conn.close();
653
    }
654
    catch(Exception e)
655
    {
656
      System.out.println("error requesting file lock from MetacatReplication." +
657
                         "handleGetLockRequest: " + e.getMessage());
658
      e.printStackTrace(System.out);
659
    }
660
  }
661
  
662
  /**
663
   * Sends all of the xml_documents information encoded in xml to a requestor
664
   * the format is:
665
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
666
   *                  user_updated, home_server, public_access, rev)/>
667
   * all of the subelements of document info are #PCDATA
668
   */
669
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params, 
670
                                        HttpServletResponse response)
671
  {
672
    String docid = ((String[])(params.get("docid")))[0];
673
    StringBuffer sb = new StringBuffer();
674
    //Connection conn = null;
675
    try
676
    {
677
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
678
                                              "handleGetDocumentInfoRequest");*/
679
      DocumentImpl doc = new DocumentImpl(docid);
680
      sb.append("<documentinfo><docid>").append(docid);
681
      sb.append("</docid><docname>").append(doc.getDocname());
682
      sb.append("</docname><doctype>").append(doc.getDoctype());
683
      sb.append("</doctype>");
684
      sb.append("<user_owner>").append(doc.getUserowner());
685
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
686
      sb.append("</user_updated>");
687
      sb.append("<home_server>");
688
      sb.append(doc.getDocHomeServer());
689
      sb.append("</home_server>");
690
      sb.append("<public_access>").append(doc.getPublicaccess());
691
      sb.append("</public_access><rev>").append(doc.getRev());
692
      sb.append("</rev></documentinfo>");
693
      response.setContentType("text/xml");
694
      out.println(sb.toString());
695
      //conn.close();
696
    }
697
    catch (Exception e)
698
    {
699
      System.out.println("error in " +
700
                         "metacatReplication.handlegetdocumentinforequest: " + 
701
                          e.getMessage());
702
    }
703
    
704
  }
705
   
706
  /**
707
   * Sends a datafile to a remote host
708
   */
709
  private void handleGetDataFileRequest(OutputStream outPut, 
710
                            Hashtable params, HttpServletResponse response)
711
                                 
712
  {
713
    //check the metacat was configured to handle data replication
714
    if (!(util.getOption("replicationsenddata")).equals("on"))
715
    {
716
      return;
717
    }
718
    
719
    String filepath = util.getOption("datafilepath");
720
    String docId = ((String[])(params.get("docid")))[0];
721
    //check if the doicd is null
722
    if (docId==null)
723
    {
724
      util.debugMessage("Didn't specify docid for replication", 20);
725
      return;
726
    }
727
    
728
    //try to open a https stream to test if the request server's public key
729
    //in the key store, this is security issue
730
    try
731
    {
732
      String server = ((String[])params.get("server"))[0];
733
      URL u = new URL("https://" + server + "?server="
734
                +util.getLocalReplicationServerName()
735
                +"&action=test");
736
      String test = MetacatReplication.getURLContent(u);
737
      //couldn't pass the test
738
      if (test.indexOf("successfully")==-1)
739
      {
740
        //response.setContentType("text/xml");
741
        //outPut.println("<error>Couldn't pass the trust test</error>");
742
        MetaCatUtil.debugMessage("Couldn't pass the trust test", 20);
743
        return;
744
      }
745
    }//try
746
    catch (Exception ee)
747
    {
748
      return;
749
    }//catch
750
  
751
    if(!filepath.endsWith("/")) 
752
    {
753
          filepath += "/";
754
    }
755
    String filename = filepath + docId;      //MIME type
756
    
757
    String contentType = null;//getServletContext().getMimeType(filename);
758
   
759
    if (contentType == null) 
760
    {
761
       if (filename.endsWith(".xml")) 
762
       {
763
          contentType="text/xml";
764
       } 
765
       else if (filename.endsWith(".css")) 
766
       {
767
          contentType="text/css";
768
       } 
769
       else if (filename.endsWith(".dtd")) 
770
       {
771
          contentType="text/plain";
772
       } 
773
       else if (filename.endsWith(".xsd")) 
774
       {
775
          contentType="text/xml";
776
       } 
777
       else if (filename.endsWith("/")) 
778
       {
779
          contentType="text/html";
780
       } 
781
       else 
782
       {
783
          File f = new File(filename);
784
          if ( f.isDirectory() ) 
785
          {
786
             contentType="text/html";
787
          } 
788
          else
789
          {
790
             contentType="application/octet-stream";
791
          }
792
       }
793
   }
794
  
795
   response.setContentType(contentType);
796
   // if we decide to use "application/octet-stream" for all data returns
797
   // response.setContentType("application/octet-stream");
798
   FileInputStream fin = null;
799
   try 
800
   {
801
      
802
      fin = new FileInputStream(filename);
803
      
804
      byte[] buf = new byte[4 * 1024]; // 4K buffer
805
      int b = fin.read(buf);
806
      while (b != -1) 
807
      {
808
        
809
        outPut.write(buf, 0, b);
810
        b = fin.read(buf);
811
      }
812
    
813
      fin.close();
814
   
815
   }  
816
   catch(Exception e)
817
   {
818
      System.out.println("error getting data file from MetacatReplication." +
819
                         "handlGetDataFileRequest " + e.getMessage());
820
      e.printStackTrace(System.out);
821
   }
822
  
823
}
824
  
825
  
826
  /**
827
   * Sends a document to a remote host
828
   */
829
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params, 
830
                                        HttpServletResponse response)
831
  {
832
    //Connection dbConn = null;
833
    try
834
    {
835
      //try to open a https stream to test if the request server's public key
836
      //in the key store, this is security issue
837
      String server = ((String[])params.get("server"))[0];
838
      URL u = new URL("https://" + server + "?server="
839
                +util.getLocalReplicationServerName()
840
                +"&action=test");
841
      String test = MetacatReplication.getURLContent(u);
842
      //couldn't pass the test
843
      if (test.indexOf("successfully")==-1)
844
      {
845
        response.setContentType("text/xml");
846
        out.println("<error>Couldn't pass the trust test</error>");
847
        return;
848
      }
849
      
850
      String docid = ((String[])(params.get("docid")))[0];
851
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
852
                                                "handleGetDocumentRequest");*/
853
      DocumentImpl di = new DocumentImpl(docid);
854
      response.setContentType("text/xml");
855
      out.print(di.toString());
856
      //conn.close();
857
      MetacatReplication.replLog("document " + docid + " sent");
858
    
859
    }
860
    catch(Exception e)
861
    {
862
      MetaCatUtil.debugMessage("error getting document from MetacatReplication."
863
                          +"handlGetDocumentRequest " + e.getMessage(), 30);
864
      //e.printStackTrace(System.out);
865
      response.setContentType("text/xml");
866
      out.println("<error>e.getMessage()</error>");
867
    }
868
    
869
  }
870
  
871
  /**
872
   * Sends a list of all of the documents on this sever along with their
873
   * revision numbers.  
874
   * The format is:
875
   * <!ELEMENT replication (server, updates)>
876
   * <!ELEMENT server (#PCDATA)>
877
   * <!ELEMENT updates ((updatedDocument | deleteDocument)*)>
878
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
879
   * <!ELEMENT deletedDocument (docid, rev)>
880
   * <!ELEMENT docid (#PCDATA)>
881
   * <!ELEMENT rev (#PCDATA)>
882
   * <!ELEMENT datafile (#PCDATA)>
883
   * note that the rev in deletedDocument is always empty.  I just left
884
   * it in there to make the parser implementation easier.
885
   */
886
  private void handleUpdateRequest(PrintWriter out, Hashtable params, 
887
                                    HttpServletResponse response)
888
  {
889
    DBConnection dbConn = null;
890
    int serialNumber = -1;
891
    PreparedStatement pstmt = null;
892
    try
893
    {
894
      //try to open a https stream to test if the request server's public key
895
      //in the key store, this is security issue
896
      String server = ((String[])params.get("server"))[0];
897
      URL u = new URL("https://" + server + "?server="
898
                +util.getLocalReplicationServerName()
899
                +"&action=test");
900
      String test = MetacatReplication.getURLContent(u);
901
      //couldn't pass the test
902
      if (test.indexOf("successfully")==-1)
903
      {
904
        response.setContentType("text/xml");
905
        out.println("<error>Couldn't pass the trust test</error>");
906
        return;
907
      }
908
      
909
      StringBuffer docsql = new StringBuffer();
910
      StringBuffer doclist = new StringBuffer();
911
      Vector packageFiles = new Vector();
912
      
913
      //get all docs that reside on this server
914
      doclist.append("<?xml version=\"1.0\"?><replication>");
915
      doclist.append("<server>").append(util.getOption("server"));
916
      doclist.append(util.getOption("replicationpath"));
917
      doclist.append("</server><updates>");
918
      
919
      docsql.append("select docid, rev, doctype from xml_documents ");
920
      if (!(util.getOption("hub")).equals("super"))
921
      {
922
        docsql.append("where server_location = 1");
923
      }
924
      
925
      //get any deleted documents
926
      StringBuffer delsql = new StringBuffer();
927
      delsql.append("select distinct docid from ");
928
      delsql.append("xml_revisions where docid not in (select docid from ");
929
      delsql.append("xml_documents) ");
930
      if (!(util.getOption("hub")).equals("super"))
931
      {
932
        delsql.append("and server_location = 1");
933
      }
934
     
935
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
936
                                                "handleUpdateRequest");*/
937
      dbConn=DBConnectionPool.
938
                  getDBConnection("MetacatReplication.handleUpdateRequest");
939
      serialNumber=dbConn.getCheckOutSerialNumber();
940
      pstmt = dbConn.prepareStatement(docsql.toString());
941
      pstmt.execute();
942
      ResultSet rs = pstmt.getResultSet();
943
      boolean tablehasrows = rs.next();
944
      //If metacat configed to replicate data file
945
      if ((util.getOption("replicationsenddata")).equals("on"))
946
      {
947
        while(tablehasrows)
948
        {
949
          String recordDoctype = rs.getString(3);
950
          Vector packagedoctypes = MetaCatUtil.getOptionList(
951
                                     MetaCatUtil.getOption("packagedoctype"));
952
          if(!packagedoctypes.contains(recordDoctype))
953
          {   //if this is a package file, put it at the end
954
              //because if a package file is read before all of the files it
955
              //refers to are loaded then there is an error
956
              if (!recordDoctype.equals("BIN"))
957
              {
958
                //for non-data file document
959
                doclist.append("<updatedDocument>");
960
                doclist.append("<docid>").append(rs.getString(1));
961
                doclist.append("</docid><rev>").append(rs.getInt(2));
962
                doclist.append("</rev>");
963
                doclist.append("</updatedDocument>");
964
              }
965
              else
966
              {
967
                //for data file document, in datafile attributes
968
                //we put "datafile" value there
969
                doclist.append("<updatedDocument>");
970
                doclist.append("<docid>").append(rs.getString(1));
971
                doclist.append("</docid><rev>").append(rs.getInt(2));
972
                doclist.append("</rev>");
973
                doclist.append("<datafile>");
974
                doclist.append(MetaCatUtil.getOption("datafileflag"));
975
                doclist.append("</datafile>");
976
                doclist.append("</updatedDocument>");
977
              } 
978
          }
979
          else
980
          { //the package files are saved to be put into the xml later.
981
              Vector v = new Vector();
982
              v.add(new String(rs.getString(1)));
983
              v.add(new Integer(rs.getInt(2)));
984
              packageFiles.add(new Vector(v));
985
          }
986
          tablehasrows = rs.next();
987
        }//while
988
      }//if
989
      else //metacat was configured not to send data file
990
      {
991
        while(tablehasrows)
992
        {
993
          String recordDoctype = rs.getString(3);
994
          if(!recordDoctype.equals("BIN")) 
995
          { //don't replicate data files
996
            Vector packagedoctypes = MetaCatUtil.getOptionList(
997
                                     MetaCatUtil.getOption("packagedoctype"));
998
            if(!packagedoctypes.contains(recordDoctype))
999
            {   //if this is a package file, put it at the end
1000
              //because if a package file is read before all of the files it
1001
              //refers to are loaded then there is an error
1002
              doclist.append("<updatedDocument>");
1003
              doclist.append("<docid>").append(rs.getString(1));
1004
              doclist.append("</docid><rev>").append(rs.getInt(2));
1005
              doclist.append("</rev>");
1006
              doclist.append("</updatedDocument>");
1007
            }
1008
            else
1009
            { //the package files are saved to be put into the xml later.
1010
              Vector v = new Vector();
1011
              v.add(new String(rs.getString(1)));
1012
              v.add(new Integer(rs.getInt(2)));
1013
              packageFiles.add(new Vector(v));
1014
            }
1015
         }//if
1016
         tablehasrows = rs.next();
1017
        }//while
1018
      }//else
1019
      
1020
      pstmt = dbConn.prepareStatement(delsql.toString());
1021
      //usage count should increas 1
1022
      dbConn.increaseUsageCount(1);
1023
      
1024
      pstmt.execute();
1025
      rs = pstmt.getResultSet();
1026
      tablehasrows = rs.next();
1027
      while(tablehasrows)
1028
      { //handle the deleted documents
1029
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1030
        doclist.append("</docid><rev></rev></deletedDocument>");
1031
        //note that rev is always empty for deleted docs
1032
        tablehasrows = rs.next();
1033
      }
1034
      
1035
      //now we can put the package files into the xml results
1036
      for(int i=0; i<packageFiles.size(); i++)
1037
      {
1038
        Vector v = (Vector)packageFiles.elementAt(i);
1039
        doclist.append("<updatedDocument>");
1040
        doclist.append("<docid>").append((String)v.elementAt(0));
1041
        doclist.append("</docid><rev>");
1042
        doclist.append(((Integer)v.elementAt(1)).intValue());
1043
        doclist.append("</rev>");
1044
        doclist.append("</updatedDocument>");
1045
      }
1046
      
1047
      doclist.append("</updates></replication>");
1048
      MetaCatUtil.debugMessage("doclist: " + doclist.toString());
1049
      pstmt.close();
1050
      //conn.close();
1051
      response.setContentType("text/xml");
1052
      out.println(doclist.toString());
1053
     
1054
    }
1055
    catch(Exception e)
1056
    {
1057
      MetaCatUtil.debugMessage("error in MetacatReplication." +
1058
                         "handleupdaterequest: " + e.getMessage(), 30);
1059
      //e.printStackTrace(System.out);
1060
      response.setContentType("text/xml");
1061
      out.println("<error>e.getMessage()</error>");
1062
    }
1063
    finally
1064
    {
1065
      try
1066
      {
1067
        pstmt.close();
1068
      }//try
1069
      catch (SQLException ee)
1070
      {
1071
        MetaCatUtil.debugMessage("Error in MetacatReplication." +
1072
                "handleUpdaterequest to close pstmt: "+ee.getMessage(), 30);
1073
      }//catch
1074
      finally
1075
      {
1076
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1077
      }//finally
1078
    }//finally
1079
        
1080
                        
1081
      
1082
    
1083
  }
1084
  
1085
  /**
1086
   * Returns the xml_catalog table encoded in xml
1087
   */
1088
  public static String getCatalogXML()
1089
  {
1090
    return handleGetCatalogRequest(null, null, null, false);
1091
  }
1092
  
1093
  /**
1094
   * Sends the contents of the xml_catalog table encoded in xml
1095
   * The xml format is:
1096
   * <!ELEMENT xml_catalog (row*)>
1097
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1098
   *                system_id)>
1099
   * All of the sub elements of row are #PCDATA
1100
   
1101
   * If printFlag == false then do not print to out.
1102
   */
1103
  private static String handleGetCatalogRequest(PrintWriter out, 
1104
                                                Hashtable params,
1105
                                                HttpServletResponse response,
1106
                                                boolean printFlag)
1107
  {
1108
    DBConnection dbConn = null;
1109
    int serialNumber = -1;
1110
    PreparedStatement pstmt = null;
1111
    try
1112
    { 
1113
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1114
                                                "handleGetCatalogRequest");*/
1115
      dbConn=DBConnectionPool.
1116
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1117
      serialNumber=dbConn.getCheckOutSerialNumber();
1118
      pstmt = dbConn.prepareStatement("select entry_type, " +
1119
                              "source_doctype, target_doctype, public_id, " +
1120
                              "system_id from xml_catalog");
1121
      pstmt.execute();
1122
      ResultSet rs = pstmt.getResultSet();
1123
      boolean tablehasrows = rs.next();
1124
      StringBuffer sb = new StringBuffer();
1125
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1126
      while(tablehasrows)
1127
      {
1128
        sb.append("<row><entry_type>").append(rs.getString(1));
1129
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1130
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1131
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1132
        sb.append("</public_id><system_id>").append(rs.getString(5));
1133
        sb.append("</system_id></row>");
1134
      
1135
        tablehasrows = rs.next();
1136
      }
1137
      sb.append("</xml_catalog>");
1138
      //conn.close();
1139
      if(printFlag)
1140
      {
1141
        response.setContentType("text/xml");
1142
        out.println(sb.toString());
1143
      }
1144
      pstmt.close();
1145
      return sb.toString();
1146
    }
1147
    catch(Exception e)
1148
    {
1149
      
1150
      System.out.println("error in MetacatReplication.handleGetCatalogRequest:"+ 
1151
                          e.getMessage());
1152
      e.printStackTrace(System.out);
1153
    }
1154
    finally
1155
    {
1156
      try
1157
      {
1158
        pstmt.close();
1159
      }//try
1160
      catch (SQLException ee)
1161
      {
1162
        MetaCatUtil.
1163
           debugMessage("Error in MetacatReplication.handleGetCatalogRequest: "
1164
           +ee.getMessage(), 30);
1165
      }//catch
1166
      finally
1167
      {
1168
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1169
      }//finally
1170
    }//finally
1171
      
1172
    return null;
1173
  }
1174
  
1175
  /**
1176
   * Sends the current system date to the remote server.  Using this action
1177
   * for replication gets rid of any problems with syncronizing clocks 
1178
   * because a time specific to a document is always kept on its home server.
1179
   */
1180
  private void handleGetTimeRequest(PrintWriter out, Hashtable params, 
1181
                                    HttpServletResponse response)
1182
  {
1183
    SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1184
    java.util.Date localtime = new java.util.Date();
1185
    String dateString = formatter.format(localtime);
1186
    response.setContentType("text/xml");
1187
    
1188
    out.println("<timestamp>" + dateString + "</timestamp>");
1189
  }
1190
  
1191
  /**
1192
   * this method handles the timeout for a file lock.  when a lock is 
1193
   * granted it is granted for 30 seconds.  When this thread runs out
1194
   * it deletes the docid from the queue, thus eliminating the lock.
1195
   */
1196
  public void run()
1197
  {
1198
    try
1199
    {
1200
      MetaCatUtil.debugMessage("thread started for docid: " + 
1201
                               (String)fileLocks.elementAt(0), 45);
1202
      
1203
      Thread.sleep(30000); //the lock will expire in 30 seconds
1204
      MetaCatUtil.debugMessage("thread for docid: " + 
1205
                             (String)fileLocks.elementAt(fileLocks.size() - 1) + 
1206
                              " exiting.");
1207
      
1208
      fileLocks.remove(fileLocks.size() - 1);
1209
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1210
      //in the vector, the first one inserted will be removed.
1211
    }
1212
    catch(Exception e)
1213
    {
1214
      MetaCatUtil.debugMessage("error in file lock thread from " + 
1215
                                  "MetacatReplication.run: " + e.getMessage());
1216
    }
1217
  }
1218
  
1219
  /**
1220
   * Returns the name of a server given a serverCode
1221
   * @param serverCode the serverid of the server
1222
   * @return the servername or null if the specified serverCode does not
1223
   *         exist.
1224
   */
1225
  public static String getServer(int serverCode)
1226
  {
1227
    //System.out.println("serverid: " + serverCode);
1228
    DBConnection dbConn = null;
1229
    int serialNumber = -1;
1230
    PreparedStatement pstmt = null;
1231
    try
1232
    {
1233
      dbConn=DBConnectionPool.
1234
                  getDBConnection("MetacatReplication.getServer");
1235
      serialNumber=dbConn.getCheckOutSerialNumber();
1236
      String sql = new String("select server from " +
1237
                              "xml_replication where serverid = " + 
1238
                              serverCode);
1239
      pstmt = dbConn.prepareStatement(sql);
1240
      //System.out.println("getserver sql: " + sql);
1241
      pstmt.execute();
1242
      ResultSet rs = pstmt.getResultSet();
1243
      boolean tablehasrows = rs.next();
1244
      if(tablehasrows)
1245
      {
1246
        //System.out.println("server: " + rs.getString(1));
1247
        return rs.getString(1);
1248
      }
1249
      
1250
      //conn.close();
1251
    }
1252
    catch(Exception e)
1253
    {
1254
      System.out.println("Error in MetacatReplication.getServer: " + 
1255
                          e.getMessage());
1256
    }
1257
    finally
1258
    {
1259
      try
1260
      {
1261
        pstmt.close();
1262
      }//try
1263
      catch (SQLException ee)
1264
      {
1265
        MetaCatUtil.debugMessage("Error in MetacactReplication.getserver: "+
1266
                                    ee.getMessage(), 30);
1267
      }//catch
1268
      finally
1269
      {
1270
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1271
      }//fianlly
1272
    }//finally
1273
        
1274
      
1275
        
1276
    return null;
1277
      //return null if the server does not exist
1278
  }
1279
  
1280
  /**
1281
   * Returns a server code given a server name
1282
   * @param server the name of the server
1283
   * @return integer > 0 representing the code of the server, 0 if the server
1284
   *  does not exist.
1285
   */
1286
  public static int getServerCode(String server) throws Exception
1287
  {
1288
    DBConnection dbConn = null;
1289
    int serialNumber = -1;
1290
    PreparedStatement pstmt = null;
1291
    int serverCode = 0;
1292

    
1293
    try {
1294

    
1295
      //conn = util.openDBConnection();
1296
      dbConn=DBConnectionPool.
1297
                  getDBConnection("MetacatReplication.getServerCode");
1298
      serialNumber=dbConn.getCheckOutSerialNumber();
1299
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1300
                                    "WHERE server LIKE '" + server + "'");
1301
      pstmt.execute();
1302
      ResultSet rs = pstmt.getResultSet();
1303
      boolean tablehasrows = rs.next();
1304
      if ( tablehasrows ) {  
1305
        serverCode = rs.getInt(1);
1306
        pstmt.close();
1307
        //conn.close();
1308
        return serverCode;
1309
      }
1310
      
1311
    } catch(Exception e) {
1312
      throw e;
1313

    
1314
    } finally {
1315
      try 
1316
      {
1317
        pstmt.close();
1318
        //conn.close();
1319
       }//try
1320
       catch(Exception ee) 
1321
       {
1322
         MetaCatUtil.debugMessage("Error in MetacatReplicatio.getServerCode: "
1323
                                  +ee.getMessage(), 30);
1324
                           
1325
       }//catch
1326
       finally
1327
       {
1328
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1329
       }//finally
1330
    }//finally
1331
    
1332
    return serverCode;
1333
  }
1334
  
1335
  /**
1336
   * This method returns the content of a url
1337
   * @param u the url to return the content from
1338
   * @return a string representing the content of the url
1339
   * @throws java.io.IOException
1340
   */
1341
  public static String getURLContent(URL u) throws java.io.IOException
1342
  {
1343
    //System.out.println("url: " + u.toString());
1344
    char istreamChar;
1345
    int istreamInt;
1346
    InputStreamReader istream = new InputStreamReader(u.openStream());
1347
    StringBuffer serverResponse = new StringBuffer();
1348
    while((istreamInt = istream.read()) != -1)
1349
    {
1350
      istreamChar = (char)istreamInt;
1351
      serverResponse.append(istreamChar);
1352
    }
1353
    
1354
    return serverResponse.toString();
1355
  }
1356
  
1357
  /**
1358
   * Method for writing replication messages to a log file specified in 
1359
   * metacat.properties
1360
   */
1361
  public static void replLog(String message)
1362
  {
1363
    try
1364
    {
1365
      FileOutputStream fos = new FileOutputStream(
1366
                                 util.getOption("replicationlog"), true);
1367
      PrintWriter pw = new PrintWriter(fos);
1368
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1369
      java.util.Date localtime = new java.util.Date();
1370
      String dateString = formatter.format(localtime);
1371
      dateString += " :: " + message;
1372
      //time stamp each entry
1373
      pw.println(dateString);
1374
      pw.flush();
1375
    }
1376
    catch(Exception e)
1377
    {
1378
      System.out.println("error writing to replication log from " +
1379
                         "MetacatReplication.replLog: " + e.getMessage());
1380
      //e.printStackTrace(System.out);
1381
    }
1382
  }
1383
  
1384
  /**
1385
   * Returns true if the replicate field for server in xml_replication is 1.
1386
   * Returns false otherwise
1387
   */
1388
  public static boolean replToServer(String server)
1389
  {
1390
    DBConnection dbConn = null;
1391
    int serialNumber = -1;
1392
    PreparedStatement pstmt = null;
1393
    try
1394
    {
1395
      dbConn=DBConnectionPool.
1396
                  getDBConnection("MetacatReplication.repltoServer");
1397
      serialNumber=dbConn.getCheckOutSerialNumber();
1398
      pstmt = dbConn.prepareStatement("select replicate from " + 
1399
                                    "xml_replication where server like '" +
1400
                                     server + "'");
1401
      pstmt.execute();
1402
      ResultSet rs = pstmt.getResultSet();
1403
      boolean tablehasrows = rs.next();
1404
      if(tablehasrows)
1405
      {
1406
        int i = rs.getInt(1);
1407
        if(i == 1)
1408
        {
1409
          pstmt.close();
1410
          //conn.close();
1411
          return true;
1412
        }
1413
        else
1414
        {
1415
          pstmt.close();
1416
          //conn.close();
1417
          return false;
1418
        }
1419
      }
1420
    }
1421
    catch(Exception e)
1422
    {
1423
      System.out.println("error in MetacatReplication.replToServer: " + 
1424
                         e.getMessage());
1425
    }
1426
    finally
1427
    {
1428
      try
1429
      {
1430
        pstmt.close();
1431
        //conn.close();
1432
      }//try
1433
      catch(Exception ee)
1434
      {
1435
        MetaCatUtil.debugMessage("Error in MetacatReplication.replToServer: "
1436
                                  +ee.getMessage(), 30);
1437
      }//catch
1438
      finally
1439
      {
1440
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1441
      }//finally
1442
    }//finally
1443
    return false;
1444
    //the default if this server does not exist is to not replicate to it.
1445
  }
1446
  
1447
  
1448
}
(34-34/43)