Project

General

Profile

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