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: berkley $'
10
 *     '$Date: 2000-12-21 09:03:27 -0800 (Thu, 21 Dec 2000) $'
11
 * '$Revision: 629 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

    
16
import java.util.*;
17
import java.io.*;
18
import java.sql.*;
19
import java.net.*;
20
import java.lang.*;
21
import java.text.*;
22
import javax.servlet.*;
23
import javax.servlet.http.*;
24

    
25
import org.xml.sax.*;
26

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

    
61
  public void doPost(HttpServletRequest request, HttpServletResponse response)
62
                     throws ServletException, IOException 
63
  {
64
    // Process the data and send back the response
65
    handleGetOrPost(request, response);
66
  }
67
  
68
  private void handleGetOrPost(HttpServletRequest request, 
69
                               HttpServletResponse response) 
70
                               throws ServletException, IOException 
71
  {
72
    PrintWriter out = response.getWriter();
73
    Hashtable params = new Hashtable();
74
    Enumeration paramlist = request.getParameterNames();
75
    
76
    while (paramlist.hasMoreElements()) 
77
    {
78
      String name = (String)paramlist.nextElement();
79
      String[] value = request.getParameterValues(name);
80
      params.put(name, value);  
81
    }
82
    
83
    if(params.containsKey("action"))
84
    {
85
      if(((String[])params.get("action"))[0].equals("stop"))
86
      { //stop the replication server
87
        replicationDaemon.cancel();
88
        out.println("Replication Handler Stopped");
89
        System.out.println("Replication Handler Stopped");
90
        MetacatReplication.replLog("deltaT handler stopped");
91
      }
92
      else if(((String[])params.get("action"))[0].equals("start"))
93
      { //start the replication server
94
        int rate;
95
        if(params.containsKey("rate"))
96
        {
97
          rate = new Integer(
98
                 new String(((String[])params.get("rate"))[0])).intValue();
99
          if(rate < 30)
100
          {
101
            out.println("Replication deltaT rate cannot be less than 30!");
102
            //deltaT<30 is a timing mess!
103
            rate = 1000;
104
          }
105
        }
106
        else
107
        {
108
          rate = 1000;
109
        }
110
        
111
        out.println("New rate is: " + rate + " seconds.");
112
        replicationDaemon.cancel();
113
        replicationDaemon = new Timer(true);
114
        replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(out), 0, 
115
                                              rate * 1000);
116
        MetacatReplication.replLog("deltaT handler started with rate=" + 
117
                                    rate + " seconds");
118
        out.println("Replication Handler Started");
119
        System.out.println("Replication Handler Started");
120
      }
121
      else if(((String[])params.get("action"))[0].equals("getall"))
122
      { //updates this server exactly once
123
        replicationDaemon.schedule(new ReplicationHandler(out), 0);
124
        out.println("<html><body>\"Get All\" Done</body></html>");
125
      }
126
      else if(((String[])params.get("action"))[0].equals("forcereplicate"))
127
      {
128
        handleForceReplicateRequest(out, params, response);
129
      }
130
      else if(((String[])params.get("action"))[0].equals("update"))
131
      { //request an update list from the server
132
        handleUpdateRequest(out, params, response);
133
      }
134
      else if(((String[])params.get("action"))[0].equals("read"))
135
      { //request a specific document from the server
136
        //note that this could be replaced by a call to metacatServlet
137
        //handleGetDocumentAction().
138
        handleGetDocumentRequest(out, params, response);
139
      }
140
      else if(((String[])params.get("action"))[0].equals("getlock"))
141
      {
142
        handleGetLockRequest(out, params, response);
143
      }
144
      else if(((String[])params.get("action"))[0].equals("getdocumentinfo"))
145
      {
146
        handleGetDocumentInfoRequest(out, params, response);
147
      }
148
      else if(((String[])params.get("action"))[0].equals("gettime"))
149
      {
150
        handleGetTimeRequest(out, params, response);
151
      }
152
      else if(((String[])params.get("action"))[0].equals("getcatalog"))
153
      {
154
        handleGetCatalogRequest(out, params, response, true);
155
      }
156
      else if(((String[])params.get("action"))[0].equals("servercontrol"))
157
      {
158
        handleServerControlRequest(out, params, response);
159
      }
160
      
161
    }
162
  }
163
  
164
  /** 
165
   * This method can add, delete and list the servers currently included in
166
   * xml_replication.
167
   * action           subaction            other needed params
168
   * ---------------------------------------------------------
169
   * servercontrol    add                  server
170
   * servercontrol    delete               server
171
   * servercontrol    list                 
172
   */
173
  private void handleServerControlRequest(PrintWriter out, Hashtable params,
174
                                          HttpServletResponse response)
175
  {
176
    String subaction = ((String[])params.get("subaction"))[0];
177
    try
178
    {
179
      Connection conn = util.openDBConnection();
180
      PreparedStatement pstmt;
181
      if(subaction.equals("add"))
182
      {
183
        String replicate = ((String[])params.get("replicate"))[0];
184
        String server = ((String[])params.get("server"))[0];
185
        pstmt = conn.prepareStatement("insert into xml_replication (server, " +
186
                "last_checked, replicate) values ('" + server + "', to_date(" +
187
                "'01/01/00', 'MM/DD/YY'), '" + replicate + "')");
188
        pstmt.execute();
189
        out.println("server " + server + " added"); 
190
      }
191
      else if(subaction.equals("delete"))
192
      {
193
        String server = ((String[])params.get("server"))[0];
194
        pstmt = conn.prepareStatement("delete from xml_replication where " +
195
                "server like '" + server + "'");
196
        pstmt.execute();
197
        out.println("server " + server + " deleted");
198
      }
199
      else if(subaction.equals("list"))
200
      {
201
        response.setContentType("text/html");
202
        out.println("<html><body><table border=\"1\">");
203
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
204
        out.println("<b>replicate</b></td></tr>");
205
        pstmt = conn.prepareStatement("select * from xml_replication");
206
        pstmt.execute();
207
        ResultSet rs = pstmt.getResultSet();
208
        boolean tablehasrows = rs.next();
209
        while(tablehasrows)
210
        {
211
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
212
          out.println(rs.getString(3) + "</td><td>");
213
          out.println(rs.getString(4) + "</td></tr>");
214
          tablehasrows = rs.next();
215
        }
216
        out.println("</table></body></html>");
217
      }
218
      conn.close();
219
    }
220
    catch(Exception e)
221
    {
222
      System.out.println("error in handleServerControlRequest " + 
223
                         e.getMessage());
224
      e.printStackTrace(System.out);
225
    }
226
  }
227
  
228
  /**
229
   * when a forcereplication request comes in, this method sends a read request
230
   * to the requesting server for the specified docid.
231
   */
232
  private void handleForceReplicateRequest(PrintWriter out, Hashtable params,
233
                                           HttpServletResponse response)
234
  {
235
    //System.out.println("in handleforcereplicaterequest");
236
    String server = ((String[])params.get("server"))[0];
237
    if(!(replToServer(server)))
238
    { //do not get the server's new document if we are not replicating from there
239
      return;
240
    }
241
    
242
    //the server that the request came from
243
    String docid = ((String[])params.get("docid"))[0];
244
    //the docid of the document to get
245
    String dbaction = "UPDATE";
246
    //default action is update
247
    boolean override = false;
248
    int serverCode = 1;
249
    
250
    try
251
    {
252
      if(params.containsKey("dbaction"))
253
      { //if the url contains a dbaction then the default action is overridden
254
        dbaction = ((String[])params.get("dbaction"))[0];
255
        serverCode = MetacatReplication.getServerCode(server);
256
        override = true; //we are now overriding the default action
257
      }
258
      MetaCatUtil.debugMessage("action in forcereplicate is: " + dbaction);
259
      MetaCatUtil.debugMessage("serverCode in forcereplicate is: " + serverCode);
260
      MetacatReplication.replLog("force replication request from " + server); 
261
      
262
      int serverCheckCode = MetacatReplication.getServerCode(server);
263
      URL u = new URL("http://" + server + "?action=read&docid=" + docid);
264
      MetaCatUtil.debugMessage("sending message: " + u.toString());
265
      String xmldoc = MetacatReplication.getURLContent(u);
266
      MetaCatUtil.debugMessage("document: " + xmldoc);
267
      //get the document to write
268
      URL docinfourl = new URL("http://" + server + 
269
                               "?action=getdocumentinfo&docid=" +
270
                               docid);
271
      //we need to get the document's info so we can set the correct user
272
      //and group once we get the document and write it to our DB
273
      MetaCatUtil.debugMessage("sending message: " + docinfourl.toString());
274
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
275
      MetaCatUtil.debugMessage("docInfo: " + docInfoStr);
276
      DocInfoHandler dih = new DocInfoHandler();
277
      //dih is the parser for the docinfo xml format
278
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
279
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
280
      Hashtable docinfoHash = dih.getDocInfo();
281
      String user = (String)docinfoHash.get("user_owner");
282
      String group = new String(user);
283
      //right now the user and group are the same.
284
      Connection conn = util.openDBConnection();
285
      DocumentImpl.write(conn, new StringReader(xmldoc), null, dbaction, docid, 
286
                         user, group, serverCode, override);
287
      MetacatReplication.replLog("document " + docid + " added to DB with " +
288
                                 "action " + dbaction);
289
      conn.close();
290
    }
291
    catch(Exception e)
292
    {
293
      System.out.println("error in metacatReplication.handleForceReplicate" +
294
                         "Request: " + e.getMessage());
295
    }
296
  }
297
  
298
  /**
299
   * Grants or denies a lock to a requesting host.
300
   * The servlet parameters of interrest are:
301
   * docid: the docid of the file the lock is being requested for
302
   * currentdate: the timestamp of the document on the remote server
303
   * 
304
   */
305
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
306
                                    HttpServletResponse response)
307
  {
308
    try
309
    {
310
      Connection conn = util.openDBConnection();
311
      String docid = ((String[])params.get("docid"))[0];
312
      String remoteRev = ((String[])params.get("updaterev"))[0];
313
      DocumentImpl requestDoc = new DocumentImpl(conn, docid);
314
      MetacatReplication.replLog("lock request for " + docid);
315
      int localRevInt = requestDoc.getRev();
316
      int remoteRevInt = Integer.parseInt(remoteRev);
317
      
318
      if(remoteRevInt >= localRevInt)
319
      {
320
        if(!fileLocks.contains(docid))
321
        { //grant the lock if it is not already locked
322
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
323
          //send a message back to the the remote host authorizing the insert
324
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
325
          lockThread = new Thread(this);
326
          lockThread.setPriority(Thread.MIN_PRIORITY);
327
          lockThread.start();
328
          System.out.println("lock granted for " + docid);
329
          MetacatReplication.replLog("lock granted for " + docid);
330
        }
331
        else
332
        { //deny the lock
333
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
334
          MetacatReplication.replLog("lock denied for " + docid + 
335
                                     "reason: file already locked");
336
        }
337
      }
338
      else
339
      {//deny the lock.
340
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
341
        MetacatReplication.replLog("lock denied for " + docid + 
342
                                   "reason: client has outdated file");
343
      }
344
      conn.close();
345
    }
346
    catch(Exception e)
347
    {
348
      System.out.println("error requesting file lock: " + e.getMessage());
349
      e.printStackTrace(System.out);
350
    }
351
  }
352
  
353
  /**
354
   * Sends all of the xml_documents information encoded in xml to a requestor
355
   * the format is:
356
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
357
   *                         user_updated, public_access, rev)
358
   * all of the subelements of document info are #PCDATA
359
   */
360
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params, 
361
                                        HttpServletResponse response)
362
  {
363
    String docid = ((String[])(params.get("docid")))[0];
364
    StringBuffer sb = new StringBuffer();
365
    try
366
    {
367
      Connection conn = util.openDBConnection();
368
      DocumentImpl doc = new DocumentImpl(conn, docid);
369
      sb.append("<documentinfo><docid>").append(docid);
370
      sb.append("</docid><docname>").append(doc.getDocname());
371
      sb.append("</docname><doctype>").append(doc.getDoctype());
372
      sb.append("</doctype><doctitle>").append(doc.getDocTitle());
373
      sb.append("</doctitle><user_owner>").append(doc.getUserowner());
374
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
375
      sb.append("</user_updated><public_access>").append(doc.getPublicaccess());
376
      sb.append("</public_access><rev>").append(doc.getRev());
377
      sb.append("</rev></documentinfo>");
378
      response.setContentType("text/xml");
379
      out.println(sb.toString());
380
      conn.close();
381
    }
382
    catch (Exception e)
383
    {
384
      System.out.println("error in metacatReplication.handlegetdocumentinforequest: " + 
385
      e.getMessage());
386
    }
387
    
388
  }
389
  
390
  /**
391
   * Sends a document to a remote host
392
   */
393
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params, 
394
                                        HttpServletResponse response)
395
  {
396
    try
397
    {
398
      String docid = ((String[])(params.get("docid")))[0];
399
      MetaCatUtil.debugMessage("incoming get request for document: " + docid);
400
      Connection conn = util.openDBConnection();
401
      DocumentImpl di = new DocumentImpl(conn, docid);
402
      response.setContentType("text/xml");
403
      out.print(di.toString());
404
      conn.close();
405
      MetacatReplication.replLog("document " + docid + " sent");
406
      System.out.println("document " + docid + " sent");
407
    }
408
    catch(Exception e)
409
    {
410
      System.out.println("error getting document: " + e.getMessage());
411
    }
412
    
413
  }
414
  
415
  /**
416
   * Sends a list of all of the documents on this sever along with their
417
   * revision numbers.  
418
   * The format is:
419
   * <!ELEMENT replication (server, updates)>
420
   * <!ELEMENT server (#PCDATA)>
421
   * <!ELEMENT updates ((updatedDocument | deleteDocument)*)>
422
   * <!ELEMENT updatedDocument (docid, rev)>
423
   * <!ELEMENT deletedDocument (docid, rev)>
424
   * <!ELEMENT docid (#PCDATA)>
425
   * <!ELEMENT rev (#PCDATA)>
426
   * note that the rev in deletedDocument is always empty.  I just left
427
   * it in there to make the parser implementation easier.
428
   */
429
  private void handleUpdateRequest(PrintWriter out, Hashtable params, 
430
                                    HttpServletResponse response)
431
  {
432
    try
433
    {
434
      System.out.println("received update request");
435
      StringBuffer docsql = new StringBuffer();
436
      StringBuffer doclist = new StringBuffer();
437
      Vector packageFiles = new Vector();
438
      
439
      //get all docs that reside on this server
440
      doclist.append("<?xml version=\"1.0\"?><replication>");
441
      doclist.append("<server>").append(util.getOption("server"));
442
      doclist.append(util.getOption("replicationpath"));
443
      doclist.append("</server><updates>");
444
      
445
      docsql.append("select docid, rev, doctype from xml_documents where "); 
446
      docsql.append("server_location = 1");
447
      
448
      //get any deleted documents
449
      StringBuffer delsql = new StringBuffer();
450
      delsql.append("select distinct docid from ");
451
      delsql.append("xml_revisions where docid not in (select docid from ");
452
      delsql.append("xml_documents) and server_location = 1");
453
      
454
      Connection conn = util.openDBConnection();
455
      PreparedStatement pstmt = conn.prepareStatement(docsql.toString());
456
      pstmt.execute();
457
      ResultSet rs = pstmt.getResultSet();
458
      boolean tablehasrows = rs.next();
459
      while(tablehasrows)
460
      {
461
        if(!rs.getString(3).equals(util.getOption("packagedoctype")))
462
        { //if this is a package file, put it at the end
463
          //because if a package file is read before all of the files it
464
          //refers to are loaded then there is an error
465
          doclist.append("<updatedDocument>");
466
          doclist.append("<docid>").append(rs.getString(1));
467
          doclist.append("</docid><rev>").append(rs.getInt(2));
468
          doclist.append("</rev>");
469
          doclist.append("</updatedDocument>");
470
        }
471
        else
472
        { //the package files are saved to be put into the xml later.
473
          Vector v = new Vector();
474
          v.add(new String(rs.getString(1)));
475
          v.add(new Integer(rs.getInt(2)));
476
          packageFiles.add(new Vector(v));
477
        }
478
        tablehasrows = rs.next();
479
      }
480
      
481
      pstmt = conn.prepareStatement(delsql.toString());
482
      pstmt.execute();
483
      rs = pstmt.getResultSet();
484
      tablehasrows = rs.next();
485
      while(tablehasrows)
486
      { //handle the deleted documents
487
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
488
        doclist.append("</docid><rev></rev></deletedDocument>");
489
        //note that rev is always empty for deleted docs
490
        tablehasrows = rs.next();
491
      }
492
      
493
      //now we can put the package files into the xml results
494
      for(int i=0; i<packageFiles.size(); i++)
495
      {
496
        Vector v = (Vector)packageFiles.elementAt(i);
497
        doclist.append("<updatedDocument>");
498
        doclist.append("<docid>").append((String)v.elementAt(0));
499
        doclist.append("</docid><rev>");
500
        doclist.append(((Integer)v.elementAt(1)).intValue());
501
        doclist.append("</rev>");
502
        doclist.append("</updatedDocument>");
503
      }
504
      
505
      doclist.append("</updates></replication>");
506
      MetaCatUtil.debugMessage("doclist: " + doclist.toString());
507
      conn.close();
508
      response.setContentType("text/xml");
509
      out.println(doclist.toString());
510
      System.out.println("doclist: " + doclist.toString());
511
      System.out.println("update request handled");
512
    }
513
    catch(Exception e)
514
    {
515
      System.out.println("error in handleupdaterequest2: " + e.getMessage());
516
      e.printStackTrace(System.out);
517
    }
518
    
519
  }
520
  
521
  /**
522
   * Returns the xml_catalog table encoded in xml
523
   */
524
  public static String getCatalogXML()
525
  {
526
    return handleGetCatalogRequest(null, null, null, false);
527
  }
528
  
529
  /**
530
   * Sends the contents of the xml_catalog table encoded in xml
531
   * The xml format is:
532
   * <!ELEMENT xml_catalog (row*)>
533
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
534
   *                system_id)>
535
   * All of the sub elements of row are #PCDATA
536
   
537
   * If printFlag == false then do not print to out.
538
   */
539
  private static String handleGetCatalogRequest(PrintWriter out, 
540
                                                Hashtable params,
541
                                                HttpServletResponse response,
542
                                                boolean printFlag)
543
  {
544
    try
545
    {
546
      Connection conn = util.openDBConnection();
547
      PreparedStatement pstmt = conn.prepareStatement("select entry_type, " +
548
                              "source_doctype, target_doctype, public_id, " +
549
                              "system_id from xml_catalog");
550
      pstmt.execute();
551
      ResultSet rs = pstmt.getResultSet();
552
      boolean tablehasrows = rs.next();
553
      StringBuffer sb = new StringBuffer();
554
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
555
      while(tablehasrows)
556
      {
557
        sb.append("<row><entry_type>").append(rs.getString(1));
558
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
559
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
560
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
561
        sb.append("</public_id><system_id>").append(rs.getString(5));
562
        sb.append("</system_id></row>");
563
      
564
        tablehasrows = rs.next();
565
      }
566
      sb.append("</xml_catalog>");
567
      conn.close();
568
      if(printFlag)
569
      {
570
        response.setContentType("text/xml");
571
        out.println(sb.toString());
572
      }
573
      return sb.toString();
574
    }
575
    catch(Exception e)
576
    {
577
      System.out.println("error in handleGetCatalogRequest: " + e.getMessage());
578
      e.printStackTrace(System.out);
579
    }
580
    return null;
581
  }
582
  
583
  /**
584
   * Sends the current system date to the remote server.  Using this action
585
   * for replication gets rid of any problems with syncronizing clocks 
586
   * because a time specific to a document is always kept on its home server.
587
   */
588
  private void handleGetTimeRequest(PrintWriter out, Hashtable params, 
589
                                    HttpServletResponse response)
590
  {
591
    SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
592
    java.util.Date localtime = new java.util.Date();
593
    String dateString = formatter.format(localtime);
594
    response.setContentType("text/xml");
595
    
596
    out.println("<timestamp>" + dateString + "</timestamp>");
597
  }
598
  
599
  /**
600
   * this method handles the timeout for a file lock.  when a lock is 
601
   * granted it is granted for 30 seconds.  When this thread runs out
602
   * it deletes the docid from the queue, thus eliminating the lock.
603
   */
604
  public void run()
605
  {
606
    try
607
    {
608
      MetaCatUtil.debugMessage("thread started for docid: " + 
609
                               (String)fileLocks.elementAt(0));
610
      System.out.println("thread started for docid: " + 
611
                               (String)fileLocks.elementAt(0));
612
      Thread.sleep(30000); //the lock will expire in 30 seconds
613
      MetaCatUtil.debugMessage("thread for docid: " + 
614
                             (String)fileLocks.elementAt(fileLocks.size() - 1) + 
615
                              " exiting.");
616
      System.out.println("thread for docid: " + 
617
                         (String)fileLocks.elementAt(fileLocks.size() - 1) + 
618
                         " exiting.");
619
      fileLocks.remove(fileLocks.size() - 1);
620
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
621
      //in the vector, the first one inserted will be removed.
622
    }
623
    catch(Exception e)
624
    {
625
      System.out.println("error in file lock thread: " + e.getMessage());
626
    }
627
  }
628
  
629
  /**
630
   * Returns the name of a server given a serverCode
631
   * @param serverCode the serverid of the server
632
   * @return the servername or null if the specified serverCode does not
633
   *         exist.
634
   */
635
  public static String getServer(int serverCode)
636
  {
637
    //System.out.println("serverid: " + serverCode);
638
    try
639
    {
640
      Connection conn = util.openDBConnection();
641
      String sql = new String("select server from " +
642
                              "xml_replication where serverid = " + 
643
                              serverCode);
644
      PreparedStatement pstmt = conn.prepareStatement(sql);
645
      //System.out.println("getserver sql: " + sql);
646
      pstmt.execute();
647
      ResultSet rs = pstmt.getResultSet();
648
      boolean tablehasrows = rs.next();
649
      if(tablehasrows)
650
      {
651
        //System.out.println("server: " + rs.getString(1));
652
        return rs.getString(1);
653
      }
654
      conn.close();
655
    }
656
    catch(Exception e)
657
    {
658
      System.out.println("Error in MetacatReplication.getServer: " + 
659
                          e.getMessage());
660
    }
661
    return null;
662
      //return null if the server does not exist
663
  }
664
  
665
  /**
666
   * Returns a server code given a server name
667
   * @param server the name of the server
668
   * @return integer > 0 representing the code of the server, 0 if the server
669
   *  does not exist.
670
   */
671
  public static int getServerCode(String server) throws Exception
672
  {
673
    try
674
    {
675
      Connection conn = util.openDBConnection();
676
      PreparedStatement pstmt = conn.prepareStatement("select serverid from " +
677
                                         "xml_replication where server " +
678
                                         "like '" + server + "'");
679
      pstmt.execute();
680
      ResultSet rs = pstmt.getResultSet();
681
      boolean tablehasrows = rs.next();
682
      int serverCode = 0;
683
      if(tablehasrows)
684
      {
685
         return rs.getInt(1);
686
      }
687
      else
688
      {
689
        return 0;
690
      }
691
    }
692
    catch(Exception e)
693
    {
694
      throw e;
695
    }
696
  }
697
  
698
  /**
699
   * This method returns the content of a url
700
   * @param u the url to return the content from
701
   * @return a string representing the content of the url
702
   * @throws java.io.IOException
703
   */
704
  public static String getURLContent(URL u) throws java.io.IOException
705
  {
706
    //System.out.println("url: " + u.toString());
707
    char istreamChar;
708
    int istreamInt;
709
    InputStreamReader istream = new InputStreamReader(u.openStream());
710
    StringBuffer serverResponse = new StringBuffer();
711
    while((istreamInt = istream.read()) != -1)
712
    {
713
      istreamChar = (char)istreamInt;
714
      serverResponse.append(istreamChar);
715
    }
716
    
717
    return serverResponse.toString();
718
  }
719
  
720
  /**
721
   * Method for writing replication messages to a log file specified in 
722
   * metacat.properties
723
   */
724
  public static void replLog(String message)
725
  {
726
    try
727
    {
728
      FileOutputStream fos = new FileOutputStream(
729
                                 util.getOption("replicationlog"), true);
730
      PrintWriter pw = new PrintWriter(fos);
731
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
732
      java.util.Date localtime = new java.util.Date();
733
      String dateString = formatter.format(localtime);
734
      dateString += " :: " + message;
735
      //time stamp each entry
736
      pw.println(dateString);
737
      pw.flush();
738
    }
739
    catch(Exception e)
740
    {
741
      System.out.println("error writing to replication log");
742
      //e.printStackTrace(System.out);
743
    }
744
  }
745
  
746
  /**
747
   * Returns true if the replicate field for server in xml_replication is 1.
748
   * Returns false otherwise
749
   */
750
  public static boolean replToServer(String server)
751
  {
752
    try
753
    {
754
      Connection conn = util.openDBConnection();
755
      PreparedStatement pstmt = conn.prepareStatement("select replicate from " + 
756
                                "xml_replication where server like '" +
757
                                server + "'");
758
      pstmt.execute();
759
      ResultSet rs = pstmt.getResultSet();
760
      boolean tablehasrows = rs.next();
761
      if(tablehasrows)
762
      {
763
        int i = rs.getInt(1);
764
        if(i == 1)
765
        {
766
          return true;
767
        }
768
        else
769
        {
770
          return false;
771
        }
772
      }
773
    }
774
    catch(Exception e)
775
    {
776
      System.out.println("error in replToServer: " + e.getMessage());
777
    }
778
    return false;
779
    //the default if this server does not exist is to not replicate to it.
780
  }
781
}
(30-30/39)