Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements replication for metacat
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Chad Berkley
7
 *
8
 *   '$Author: leinfelder $'
9
 *     '$Date: 2008-10-13 10:42:21 -0700 (Mon, 13 Oct 2008) $'
10
 * '$Revision: 4449 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat;
28

    
29
import java.util.*;
30
import java.util.Date;
31
import java.io.*;
32
import java.sql.*;
33
import java.net.*;
34
import java.text.*;
35

    
36
import javax.servlet.*;
37
import javax.servlet.http.*;
38

    
39
import edu.ucsb.nceas.metacat.service.DatabaseService;
40
import edu.ucsb.nceas.metacat.service.PropertyService;
41
import edu.ucsb.nceas.metacat.service.SessionService;
42
import edu.ucsb.nceas.metacat.util.LDAPUtil;
43
import edu.ucsb.nceas.metacat.util.MetaCatUtil;
44
import edu.ucsb.nceas.metacat.util.SessionData;
45
import edu.ucsb.nceas.metacat.util.SystemUtil;
46
import edu.ucsb.nceas.utilities.GeneralPropertyException;
47
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
48

    
49
import org.apache.log4j.Logger;
50
import org.xml.sax.*;
51

    
52
public class MetacatReplication extends HttpServlet implements Runnable
53
{
54

    
55
  private static final long serialVersionUID = -2898600143193513155L;
56
  private long timeInterval;
57
  private Date firstTime;
58
  private boolean timedReplicationIsOn = false;
59
  Timer replicationDaemon;
60
  private Vector fileLocks = new Vector();
61
  private Thread lockThread = null;
62
  public static final String FORCEREPLICATEDELETE = "forcereplicatedelete";
63
  private static final String TIMEREPLICATION = "replication.timedreplication";
64
  private static final String TIMEREPLICATIONINTERVAl = "replication.timedreplicationinterval";
65
  private static final String FIRSTTIME  = "replication.firsttimedreplication";
66
  private static final int    TIMEINTERVALLIMIT = 7200000;
67
  private static Logger logMetacat = Logger.getLogger(MetacatReplication.class);
68
  public static final String REPLICATIONUSER = "replication";
69

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

    
114
  public void destroy()
115
  {
116
    replicationDaemon.cancel();
117
   
118
  }
119

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

    
127
  public void doPost(HttpServletRequest request, HttpServletResponse response)
128
                     throws ServletException, IOException
129
  {
130
    // Process the data and send back the response
131
    handleGetOrPost(request, response);
132
  }
133

    
134
  private void handleGetOrPost(HttpServletRequest request,
135
                               HttpServletResponse response)
136
                               throws ServletException, IOException
137
  {
138
    //PrintWriter out = response.getWriter();
139
    //ServletOutputStream outPut = response.getOutputStream();
140
    Hashtable params = new Hashtable();
141
    Enumeration paramlist = request.getParameterNames();
142

    
143

    
144

    
145
// NOT NEEDED - doesn't provide enough security because of possible IP spoofing
146
// REPLACED with running replication comminications over HTTPS
147
//    String requestingServerIP = request.getRemoteAddr();
148
//    InetAddress iaddr = InetAddress.getByName(requestingServerIP);
149
//    String requestingServer = iaddr.getHostName();
150

    
151
    while (paramlist.hasMoreElements()) {
152
      String name = (String)paramlist.nextElement();
153
      String[] value = request.getParameterValues(name);
154
      params.put(name, value);
155
    }
156

    
157
    String action = ((String[])params.get("action"))[0];
158
    String server = null;
159

    
160
    try {
161
      // check if the server is included in the list of replicated servers
162
      if ( !action.equals("servercontrol") &&
163
           !action.equals("stop") &&
164
           !action.equals("start") &&
165
           !action.equals("getall") ) {
166

    
167
        server = ((String[])params.get("server"))[0];
168
        if ( getServerCodeForServerName(server) == 0 ) {
169
          System.out.println("Action \"" + action +
170
                             "\" rejected for server: " + server);
171
          return;
172
        } else {
173
          System.out.println("Action \"" + action +
174
                             "\" accepted for server: " + server);
175
        }
176
      }
177
      else
178
      {
179
          // start, stop, getall and servercontrol need to check
180
          // if user is administor
181
          HttpSession sess = request.getSession(true);
182
          SessionData sessionData = null;
183
          String sess_id = "";
184
          String username = "";
185
          String[] groupnames = {""};
186

    
187
          if (params.containsKey("sessionid")) 
188
          {
189
             sess_id = ((String[]) params.get("sessionid"))[0];
190
             logMetacat.info("in has sessionid "+ sess_id);
191
             if (SessionService.isSessionRegistered(sess_id)) 
192
             {
193
                  logMetacat.info("find the id " + sess_id + " in hash table");
194
                  sessionData = SessionService.getRegisteredSession(sess_id);
195
             }
196
           } 
197
          if (sessionData == null) {
198
        	  sessionData = new SessionData(sess.getId(), 
199
					(String) sess.getAttribute("username"), 
200
					(String[]) sess.getAttribute("groups"),
201
					(String) sess.getAttribute("password"));
202
          }
203
          
204
           username = sessionData.getUserName();
205
           logMetacat.warn("The user name from session is: "+ username);
206
           groupnames = sessionData.getGroupNames();
207
           if (!LDAPUtil.isAdministrator(username, groupnames)) 
208
           {
209
               PrintWriter out = response.getWriter();
210
               out.print("<error>");
211
               out.print("The user \"" + username +
212
                       "\" is not authorized for this action.");
213
               out.print("</error>");
214
               out.close();
215
               logMetacat.warn("The user \"" + username +
216
                       "\" is not authorized for this action: " +action);
217
               replErrorLog("The user \"" + username +
218
                       "\" is not authorized for this action: " +action);
219
               return;
220
           }
221
                        
222
      }// this is final else
223
    } catch (Exception e) {
224
      System.out.println("Error in MetacatReplication.handleGetOrPost: " +
225
                         e.getMessage() );
226
      return;
227
    }
228
    
229
    if ( action.equals("readdata") )
230
    {
231
      OutputStream outStream = response.getOutputStream();
232
      //to get the data file.
233
      handleGetDataFileRequest(outStream, params, response);
234
      outStream.close();
235
    }
236
    else if ( action.equals("forcereplicatedatafile") )
237
    {
238
      //read a specific docid from remote host, and store it into local host
239
      handleForceReplicateDataFileRequest(params, request);
240

    
241
    }
242
    else
243
    {
244
    PrintWriter out = response.getWriter();
245
    if ( action.equals("stop") ) {
246
      //stop the replication server
247
      replicationDaemon.cancel();
248
      replicationDaemon = new Timer(true);
249
      timedReplicationIsOn = false;
250
      try {
251
    	  PropertyService.setProperty(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
252
      } catch (GeneralPropertyException gpe) {
253
    	  logMetacat.warn("Could not set " + TIMEREPLICATION + " property: " + gpe.getMessage());
254
      }
255
      out.println("Replication Handler Stopped");
256
      MetacatReplication.replLog("deltaT handler stopped");
257

    
258

    
259
    } else if ( action.equals("start") ) {
260
       String firstTimeStr = "";
261
      //start the replication server
262
       if ( params.containsKey("rate") ) {
263
        timeInterval = new Long(
264
               new String(((String[])params.get("rate"))[0])).longValue();
265
        if(timeInterval < TIMEINTERVALLIMIT) {
266
            out.println("Replication deltaT rate cannot be less than "+
267
                    TIMEINTERVALLIMIT + " millisecs and system automatically setup the rate to "+TIMEINTERVALLIMIT);
268
            //deltaT<30 is a timing mess!
269
            timeInterval = TIMEINTERVALLIMIT;
270
        }
271
      } else {
272
        timeInterval = TIMEINTERVALLIMIT ;
273
      }
274
      logMetacat.info("New rate is: " + timeInterval + " mini seconds.");
275
      if ( params.containsKey("firsttime"))
276
      {
277
         firstTimeStr = ((String[])params.get("firsttime"))[0];
278
         try
279
         {
280
           firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
281
           logMetacat.info("The first time setting is "+firstTime.toString());
282
         }
283
         catch (Exception e)
284
         {
285
            throw new ServletException(e.getMessage());
286
         }
287
         logMetacat.warn("After combine current time, the real first time is "
288
                                  +firstTime.toString()+" minisec");
289
      }
290
      else
291
      {
292
          MetacatReplication.replErrorLog("You should specify the first time " +
293
                                          "to start a time replication");
294
          logMetacat.warn("You should specify the first time " +
295
                                  "to start a time replication");
296
          return;
297
      }
298
      
299
      timedReplicationIsOn = true;
300
      try {
301
      // save settings to property file
302
      PropertyService.setProperty(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
303
      // note we couldn't use firstTime object because it has date info
304
      // we only need time info such as 10:00 PM
305
      PropertyService.setProperty(FIRSTTIME, firstTimeStr);
306
      PropertyService.setProperty(TIMEREPLICATIONINTERVAl, (new Long(timeInterval)).toString());
307
      } catch (GeneralPropertyException gpe) {
308
    	  logMetacat.warn("Could not set property: " + gpe.getMessage());
309
      }
310
      replicationDaemon.cancel();
311
      replicationDaemon = new Timer(true);
312
      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime,
313
                                            timeInterval);
314
      out.println("Replication Handler Started");
315
      MetacatReplication.replLog("deltaT handler started with rate=" +
316
                                    timeInterval + " milliseconds at " +firstTime.toString());
317

    
318

    
319
    } else if ( action.equals("getall") ) {
320
      //updates this server exactly once
321
      replicationDaemon.schedule(new ReplicationHandler(), 0);
322
      response.setContentType("text/html");
323
      out.println("<html><body>\"Get All\" Done</body></html>");
324

    
325
    } else if ( action.equals("forcereplicate") ) {
326
      //read a specific docid from remote host, and store it into local host
327
      handleForceReplicateRequest(out, params, response, request);
328

    
329
    } else if ( action.equals(FORCEREPLICATEDELETE) ) {
330
      //read a specific docid from remote host, and store it into local host
331
      handleForceReplicateDeleteRequest(out, params, response, request);
332

    
333
    } else if ( action.equals("update") ) {
334
      //request an update list from the server
335
      handleUpdateRequest(out, params, response);
336

    
337
    } else if ( action.equals("read") ) {
338
      //request a specific document from the server
339
      //note that this could be replaced by a call to metacatServlet
340
      //handleGetDocumentAction().
341
      handleGetDocumentRequest(out, params, response);
342
    } else if ( action.equals("getlock") ) {
343
      handleGetLockRequest(out, params, response);
344

    
345
    } else if ( action.equals("getdocumentinfo") ) {
346
      handleGetDocumentInfoRequest(out, params, response);
347

    
348
    } else if ( action.equals("gettime") ) {
349
      handleGetTimeRequest(out, params, response);
350

    
351
    } else if ( action.equals("getcatalog") ) {
352
      handleGetCatalogRequest(out, params, response, true);
353

    
354
    } else if ( action.equals("servercontrol") ) {
355
      handleServerControlRequest(out, params, response);
356
    } else if ( action.equals("test") ) {
357
      response.setContentType("text/html");
358
      out.println("<html><body>Test successfully</body></html>");
359
    }
360

    
361
    out.close();
362
    }//else
363
  }
364

    
365
  /**
366
   * This method can add, delete and list the servers currently included in
367
   * xml_replication.
368
   * action           subaction            other needed params
369
   * ---------------------------------------------------------
370
   * servercontrol    add                  server
371
   * servercontrol    delete               server
372
   * servercontrol    list
373
   */
374
  private void handleServerControlRequest(PrintWriter out, Hashtable params,
375
                                          HttpServletResponse response)
376
  {
377
    String subaction = ((String[])params.get("subaction"))[0];
378
    DBConnection dbConn = null;
379
    int serialNumber = -1;
380
    PreparedStatement pstmt = null;
381
    String replicate =null;
382
    String server = null;
383
    String dataReplicate = null;
384
    String hub = null;
385
    try {
386
      //conn = util.openDBConnection();
387
      dbConn=DBConnectionPool.
388
               getDBConnection("MetacatReplication.handleServerControlRequest");
389
      serialNumber=dbConn.getCheckOutSerialNumber();
390

    
391
      // add server to server list
392
      if ( subaction.equals("add") ) {
393
        replicate = ((String[])params.get("replicate"))[0];
394
        server = ((String[])params.get("server"))[0];
395

    
396
        //Get data replication value
397
        dataReplicate = ((String[])params.get("datareplicate"))[0];
398
        //Get hub value
399
        hub = ((String[])params.get("hub"))[0];
400

    
401
        /*pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
402
                  "(server, last_checked, replicate, datareplicate, hub) " +
403
                                      "VALUES ('" + server + "', to_date(" +
404
                                      "'01/01/00', 'MM/DD/YY'), '" +
405
                                      replicate +"', '" +dataReplicate+"', '"
406
                                      + hub +"')");*/
407
        pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
408
                  "(server, last_checked, replicate, datareplicate, hub) " +
409
                                      "VALUES ('" + server + "', "+
410
                                      DatabaseService.getDBAdapter().toDate("01/01/1980", "MM/DD/YYYY")
411
                                      + ", '" +
412
                                      replicate +"', '" +dataReplicate+"', '"
413
                                      + hub +"')");
414

    
415
        pstmt.execute();
416
        pstmt.close();
417
        dbConn.commit();
418
        out.println("Server " + server + " added");
419
        response.setContentType("text/html");
420
        out.println("<html><body><table border=\"1\">");
421
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
422
        out.println("<b>replicate</b></td>");
423
        out.println("<td><b>datareplicate</b></td>");
424
        out.println("<td><b>hub</b></td></tr>");
425
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
426
        //increase dbconnection usage
427
        dbConn.increaseUsageCount(1);
428

    
429
        pstmt.execute();
430
        ResultSet rs = pstmt.getResultSet();
431
        boolean tablehasrows = rs.next();
432
        while(tablehasrows) {
433
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
434
          out.println(rs.getString(3) + "</td><td>");
435
          out.println(rs.getString(4) + "</td><td>");
436
          out.println(rs.getString(5) + "</td><td>");
437
          out.println(rs.getString(6) + "</td></tr>");
438

    
439
          tablehasrows = rs.next();
440
        }
441
        out.println("</table></body></html>");
442

    
443
        // download certificate with the public key on this server
444
        // and import it as a trusted certificate
445
        String certURL = ((String[])params.get("certificate"))[0];
446
        downloadCertificate(certURL);
447

    
448
      // delete server from server list
449
      } else if ( subaction.equals("delete") ) {
450
        server = ((String[])params.get("server"))[0];
451
        pstmt = dbConn.prepareStatement("DELETE FROM xml_replication " +
452
                                      "WHERE server LIKE '" + server + "'");
453
        pstmt.execute();
454
        pstmt.close();
455
        dbConn.commit();
456
        out.println("Server " + server + " deleted");
457
        response.setContentType("text/html");
458
        out.println("<html><body><table border=\"1\">");
459
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
460
        out.println("<b>replicate</b></td>");
461
        out.println("<td><b>datareplicate</b></td>");
462
        out.println("<td><b>hub</b></td></tr>");
463

    
464
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
465
        //increase dbconnection usage
466
        dbConn.increaseUsageCount(1);
467
        pstmt.execute();
468
        ResultSet rs = pstmt.getResultSet();
469
        boolean tablehasrows = rs.next();
470
        while(tablehasrows)
471
        {
472
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
473
          out.println(rs.getString(3) + "</td><td>");
474
          out.println(rs.getString(4) + "</td><td>");
475
          out.println(rs.getString(5) + "</td><td>");
476
          out.println(rs.getString(6) + "</td></tr>");
477
          tablehasrows = rs.next();
478
        }
479
        out.println("</table></body></html>");
480

    
481
      // list servers in server list
482
      } else if ( subaction.equals("list") ) {
483
        response.setContentType("text/html");
484
        out.println("<html><body><table border=\"1\">");
485
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
486
        out.println("<b>replicate</b></td>");
487
        out.println("<td><b>datareplicate</b></td>");
488
        out.println("<td><b>hub</b></td></tr>");
489
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
490
        pstmt.execute();
491
        ResultSet rs = pstmt.getResultSet();
492
        boolean tablehasrows = rs.next();
493
        while(tablehasrows) {
494
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
495
          out.println(rs.getString(3) + "</td><td>");
496
          out.println(rs.getString(4) + "</td><td>");
497
          out.println(rs.getString(5) + "</td><td>");
498
          out.println(rs.getString(6) + "</td></tr>");
499
          tablehasrows = rs.next();
500
        }
501
        out.println("</table></body></html>");
502
      }
503
      else
504
      {
505

    
506
        out.println("<error>Unkonwn subaction</error>");
507

    
508
      }
509
      pstmt.close();
510
      //conn.close();
511

    
512
    } catch(Exception e) {
513
      System.out.println("Error in " +
514
                         "MetacatReplication.handleServerControlRequest " +
515
                         e.getMessage());
516
      e.printStackTrace(System.out);
517
    }
518
    finally
519
    {
520
      try
521
      {
522
        pstmt.close();
523
      }//try
524
      catch (SQLException ee)
525
      {
526
        logMetacat.error("Error in " +
527
                "MetacatReplication.handleServerControlRequest to close pstmt "
528
                 + ee.getMessage());
529
      }//catch
530
      finally
531
      {
532
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
533
      }//finally
534
    }//finally
535

    
536
  }
537

    
538
   	// download certificate with the public key from certURL and
539
	// upload it onto this server; it then must be imported as a
540
	// trusted certificate
541
	private void downloadCertificate(String certURL) throws FileNotFoundException,
542
			IOException, MalformedURLException, PropertyNotFoundException {
543
		
544
		// the path to be uploaded to
545
		String certPath = SystemUtil.getContextDir(); 
546

    
547
		// get filename from the URL of the certificate
548
		String filename = certURL;
549
		int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
550
		if (slash > -1) {
551
			filename = filename.substring(slash + 1);
552
		}
553

    
554
		// open file output strem to write the input into it
555
		File f = new File(certPath, filename);
556
		synchronized (f) {
557
			try {
558
				if (f.exists()) {
559
					throw new IOException("File already exist: " + f.getCanonicalFile());
560
					// if ( f.exists() && !f.canWrite() ) {
561
					// throw new IOException("Not writable: " +
562
					// f.getCanonicalFile());
563
				}
564
			} catch (SecurityException se) {
565
				// if a security manager exists,
566
				// its checkRead method is called for f.exist()
567
				// or checkWrite method is called for f.canWrite()
568
				throw se;
569
			}
570

    
571
			// create a buffered byte output stream
572
			// that uses a default-sized output buffer
573
			FileOutputStream fos = new FileOutputStream(f);
574
			BufferedOutputStream out = new BufferedOutputStream(fos);
575

    
576
			// this should be http url
577
			URL url = new URL(certURL);
578
			BufferedInputStream bis = null;
579
			try {
580
				bis = new BufferedInputStream(url.openStream());
581
				byte[] buf = new byte[4 * 1024]; // 4K buffer
582
				int b = bis.read(buf);
583
				while (b != -1) {
584
					out.write(buf, 0, b);
585
					b = bis.read(buf);
586
				}
587
			} finally {
588
				if (bis != null)
589
					bis.close();
590
			}
591
			// the input and the output streams must be closed
592
			bis.close();
593
			out.flush();
594
			out.close();
595
			fos.close();
596
		} // end of synchronized(f)
597
	}
598

    
599
  /**
600
	 * when a forcereplication request comes in, local host sends a read request
601
	 * to the requesting server (remote server) for the specified docid. Then
602
	 * store it in local database.
603
	 */
604
  private void handleForceReplicateRequest(PrintWriter out, Hashtable params,
605
                                           HttpServletResponse response, HttpServletRequest request)
606
  {
607
    String server = ((String[])params.get("server"))[0]; // the server that
608
    String docid = ((String[])params.get("docid"))[0]; // sent the document
609
    String dbaction = "UPDATE"; // the default action is UPDATE
610
    boolean override = false;
611
    int serverCode = 1;
612
    DBConnection dbConn = null;
613
    int serialNumber = -1;
614

    
615
    try {
616
      //if the url contains a dbaction then the default action is overridden
617
      if(params.containsKey("dbaction")) {
618
        dbaction = ((String[])params.get("dbaction"))[0];
619
        //serverCode = MetacatReplication.getServerCode(server);
620
        //override = true; //we are now overriding the default action
621
      }
622
      MetacatReplication.replLog("force replication request from " + server);
623
      logMetacat.info("Force replication request from: "+ server);
624
      logMetacat.info("Force replication docid: "+docid);
625
      logMetacat.info("Force replication action: "+dbaction);
626
      // sending back read request to remote server
627
      URL u = new URL("https://" + server + "?server="
628
                +MetaCatUtil.getLocalReplicationServerName()
629
                +"&action=read&docid=" + docid);
630
      String xmldoc = MetacatReplication.getURLContent(u);
631

    
632
      // get the document info from server
633
      URL docinfourl = new URL("https://" + server +
634
                               "?server="+MetaCatUtil.getLocalReplicationServerName()
635
                               +"&action=getdocumentinfo&docid=" + docid);
636

    
637
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
638

    
639
      //dih is the parser for the docinfo xml format
640
      DocInfoHandler dih = new DocInfoHandler();
641
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
642
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
643
      Hashtable docinfoHash = dih.getDocInfo();
644

    
645
      // Get user owner of this docid
646
      String user = (String)docinfoHash.get("user_owner");
647
      // Get home server of this docid
648
      String homeServer=(String)docinfoHash.get("home_server");
649
      String createdDate = (String)docinfoHash.get("date_created");
650
      String updatedDate = (String)docinfoHash.get("date_updated");
651
      logMetacat.info("homeServer: "+homeServer);
652
      // Get Document type
653
      String docType = (String)docinfoHash.get("doctype");
654
      logMetacat.info("docType: "+docType);
655
      String parserBase = null;
656
      // this for eml2 and we need user eml2 parser
657
      if (docType != null &&
658
          (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
659
      {
660
         logMetacat.warn("This is an eml200 document!");
661
         parserBase = DocumentImpl.EML200;
662
      }
663
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE))
664
      {
665
         logMetacat.warn("This is an eml2.0.1 document!");
666
         parserBase = DocumentImpl.EML200;
667
      }
668
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE))
669
      {
670
         logMetacat.warn("This is an eml2.1.0 document!");
671
         parserBase = DocumentImpl.EML210;
672
      }
673
      logMetacat.warn("The parserBase is: "+parserBase);
674

    
675
      // Get DBConnection from pool
676
      dbConn=DBConnectionPool.
677
              getDBConnection("MetacatReplication.handleForceReplicateRequest");
678
      serialNumber=dbConn.getCheckOutSerialNumber();
679
      // write the document to local database
680
      DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false);
681
      //try this independently so we can set
682
      Exception writeException = null; 
683
      try {
684
	      wrapper.writeReplication(dbConn, new StringReader(xmldoc), null, null,
685
	                               dbaction, docid, user, null, homeServer, 
686
	                               server, createdDate, updatedDate);
687
      }
688
      catch (Exception e) {
689
    	  writeException = e;
690
      }
691

    
692
      //process extra access rules before dealing with the write exception (doc exist already)
693
      Vector accessControlList = (Vector) docinfoHash.get("accessControl");
694
      if (accessControlList != null) {
695
    	  for (int i = 0; i < accessControlList.size(); i++) {
696
        	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
697
        	  acfsf.insertPermissions();
698
        	  MetacatReplication.replLog("document " + docid + " permissions added to DB");
699
          }
700
      }
701
      
702
      if (writeException != null) {
703
    	  throw writeException;
704
      }
705
      
706
      MetacatReplication.replLog("document " + docid + " added to DB with " +
707
                                 "action " + dbaction);
708
      EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
709
    }//try
710
    catch(Exception e)
711
    {
712
      MetacatReplication.replErrorLog("document " + docid +
713
                                      " failed to added to DB with " +
714
                                      "action " + dbaction + " because "+
715
                                       e.getMessage());
716
      logMetacat.error("ERROR in MetacatReplication.handleForceReplicate" +
717
                         "Request(): " + e.getMessage());
718

    
719
    }//catch
720
    finally
721
    {
722
      // Return the checked out DBConnection
723
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
724
    }//finally
725
  }
726

    
727
/*
728
 * when a forcereplication delete request comes in, local host will delete this
729
 * document
730
 */
731
private void handleForceReplicateDeleteRequest(PrintWriter out, Hashtable params,
732
                                         HttpServletResponse response, HttpServletRequest request)
733
{
734
  String server = ((String[])params.get("server"))[0]; // the server that
735
  String docid = ((String[])params.get("docid"))[0]; // sent the document
736
  try
737
  {
738
    MetacatReplication.replLog("force replication delete request from " + server);
739
    MetacatReplication.replLog("force replication delete docid " + docid);
740
    logMetacat.info("Force replication delete request from: "+ server);
741
    logMetacat.info("Force replication delete docid: "+docid);
742
    DocumentImpl.delete(docid, null, null, server);
743
    MetacatReplication.replLog("document " + docid + " was successfully deleted ");
744
    EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, "delete");
745
    logMetacat.info("document " + docid + " was successfully deleted ");
746
  }
747
  catch(Exception e)
748
  {
749
    MetacatReplication.replErrorLog("document " + docid +
750
                                    " failed to delete because "+
751
                                     e.getMessage());
752
    logMetacat.error("ERROR in MetacatReplication.handleForceDeleteReplicate" +
753
                       "Request(): " + e.getMessage());
754

    
755
  }//catch
756

    
757
}
758

    
759

    
760
  /**
761
   * when a forcereplication data file request comes in, local host sends a
762
   * readdata request to the requesting server (remote server) for the specified
763
   * docid. Then store it in local database and file system
764
   */
765
  private void handleForceReplicateDataFileRequest(Hashtable params, HttpServletRequest request)
766
  {
767

    
768
    //make sure there is some parameters
769
    if(params.isEmpty())
770
    {
771
      return;
772
    }
773
    // Get remote server
774
    String server = ((String[])params.get("server"))[0];
775
    // the docid should include rev number
776
    String docid = ((String[])params.get("docid"))[0];
777
    // Make sure there is a docid and server
778
    if (docid==null || server==null || server.equals(""))
779
    {
780
      logMetacat.error("Didn't specify docid or server for replication");
781
      return;
782
    }
783

    
784
    // Overide or not
785
    boolean override = false;
786
    // dbaction - update or insert
787
    String dbaction=null;
788

    
789
    try
790
    {
791
      //docid was switch to two parts uinque code and rev
792
      //String uniqueCode=MetaCatUtil.getDocIdFromString(docid);
793
      //int rev=MetaCatUtil.getVersionFromString(docid);
794
      if(params.containsKey("dbaction"))
795
      {
796
        dbaction = ((String[])params.get("dbaction"))[0];
797
      }
798
      else//default value is update
799
      {
800
        dbaction = "update";
801
      }
802

    
803
      MetacatReplication.replLog("force replication request from " + server);
804
      logMetacat.info("Force replication request from: "+ server);
805
      logMetacat.info("Force replication docid: "+docid);
806
      logMetacat.info("Force replication action: "+dbaction);
807
      // get the document info from server
808
      URL docinfourl = new URL("https://" + server +
809
                               "?server="+MetaCatUtil.getLocalReplicationServerName()
810
                               +"&action=getdocumentinfo&docid=" + docid);
811

    
812
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
813

    
814
      //dih is the parser for the docinfo xml format
815
      DocInfoHandler dih = new DocInfoHandler();
816
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
817
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
818
      Hashtable docinfoHash = dih.getDocInfo();
819
      String user = (String)docinfoHash.get("user_owner");
820

    
821
      String docName = (String)docinfoHash.get("docname");
822

    
823
      String docType = (String)docinfoHash.get("doctype");
824

    
825
      String docHomeServer= (String)docinfoHash.get("home_server");
826
      
827
      String createdDate = (String)docinfoHash.get("date_created");
828
      
829
      String updatedDate = (String)docinfoHash.get("date_updated");
830
      logMetacat.info("docHomeServer of datafile: "+docHomeServer);
831

    
832

    
833

    
834
      //if action is delete, we don't delete the data file. Just archieve
835
      //the xml_documents
836
      /*if (dbaction.equals("delete"))
837
      {
838
        //conn = util.getConnection();
839
        DocumentImpl.delete(docid,user,null);
840
        //util.returnConnection(conn);
841
      }*/
842
      //To data file insert or update is same
843
      if (dbaction.equals("insert")||dbaction.equals("update"))
844
      {
845
        //Get data file and store it into local file system.
846
        // sending back readdata request to server
847
        URL url = new URL("https://" + server + "?server="
848
                +MetaCatUtil.getLocalReplicationServerName()
849
                +"&action=readdata&docid=" + docid);
850
        String datafilePath = PropertyService.getProperty("application.datafilepath");
851
        
852
        Exception writeException = null;
853
        //register data file into xml_documents table and wite data file
854
        //into file system
855
        try {
856
        	DocumentImpl.writeDataFileInReplication(url.openStream(), datafilePath,
857
                            docName, docType, docid, user,docHomeServer,server, 
858
                            DocumentImpl.DOCUMENTTABLE, false, createdDate, updatedDate);
859
        }
860
        catch (Exception e) {
861
        	writeException = e;
862
		}
863
        //process extra access rules
864
        Vector accessControlList = (Vector) docinfoHash.get("accessControl");
865
        if (accessControlList != null) {
866
      	  for (int i = 0; i < accessControlList.size(); i++) {
867
          	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
868
          	  acfsf.insertPermissions();
869
          	  MetacatReplication.replLog("datafile " + docid + " permissions added to DB");
870
            }
871
        }
872
        
873
        if (writeException != null) {
874
        	throw writeException;
875
        }
876
        
877
        //false means non-timed replication
878
        MetacatReplication.replLog("datafile " + docid + " added to DB with " +
879
                "action " + dbaction);
880
        EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
881
     }
882
    
883
    }
884
    catch(Exception e)
885
    {
886

    
887
      MetacatReplication.replErrorLog("Datafile " + docid +
888
                                      " failed to added to DB with " +
889
                                      "action " + dbaction + " because "+
890
                                       e.getMessage());
891
      logMetacat.error
892
              ("ERROR in MetacatReplication.handleForceDataFileReplicate" +
893
                         "Request(): " + e.getMessage());
894
    }
895
  }
896
  /**
897
   * Grants or denies a lock to a requesting host.
898
   * The servlet parameters of interrest are:
899
   * docid: the docid of the file the lock is being requested for
900
   * currentdate: the timestamp of the document on the remote server
901
   *
902
   */
903
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
904
                                    HttpServletResponse response)
905
  {
906

    
907
    try
908
    {
909

    
910
      String docid = ((String[])params.get("docid"))[0];
911
      String remoteRev = ((String[])params.get("updaterev"))[0];
912
      DocumentImpl requestDoc = new DocumentImpl(docid);
913
      MetacatReplication.replLog("lock request for " + docid);
914
      int localRevInt = requestDoc.getRev();
915
      int remoteRevInt = Integer.parseInt(remoteRev);
916

    
917
      if(remoteRevInt >= localRevInt)
918
      {
919
        if(!fileLocks.contains(docid))
920
        { //grant the lock if it is not already locked
921
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
922
          //send a message back to the the remote host authorizing the insert
923
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
924
          lockThread = new Thread(this);
925
          lockThread.setPriority(Thread.MIN_PRIORITY);
926
          lockThread.start();
927
          MetacatReplication.replLog("lock granted for " + docid);
928
        }
929
        else
930
        { //deny the lock
931
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
932
          MetacatReplication.replLog("lock denied for " + docid +
933
                                     "reason: file already locked");
934
        }
935
      }
936
      else
937
      {//deny the lock.
938
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
939
        MetacatReplication.replLog("lock denied for " + docid +
940
                                   "reason: client has outdated file");
941
      }
942
      //conn.close();
943
    }
944
    catch(Exception e)
945
    {
946
      System.out.println("error requesting file lock from MetacatReplication." +
947
                         "handleGetLockRequest: " + e.getMessage());
948
      e.printStackTrace(System.out);
949
    }
950
  }
951

    
952
  /**
953
   * Sends all of the xml_documents information encoded in xml to a requestor
954
   * the format is:
955
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
956
   *                  user_updated, home_server, public_access, rev)/>
957
   * all of the subelements of document info are #PCDATA
958
   */
959
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params,
960
                                        HttpServletResponse response)
961
  {
962
    String docid = ((String[])(params.get("docid")))[0];
963
    StringBuffer sb = new StringBuffer();
964

    
965
    try
966
    {
967

    
968
      DocumentImpl doc = new DocumentImpl(docid);
969
      sb.append("<documentinfo><docid>").append(docid);
970
      sb.append("</docid><docname>").append(doc.getDocname());
971
      sb.append("</docname><doctype>").append(doc.getDoctype());
972
      sb.append("</doctype>");
973
      sb.append("<user_owner>").append(doc.getUserowner());
974
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
975
      sb.append("</user_updated>");
976
      sb.append("<date_created>");
977
      sb.append(doc.getCreateDate());
978
      sb.append("</date_created>");
979
      sb.append("<date_updated>");
980
      sb.append(doc.getUpdateDate());
981
      sb.append("</date_updated>");
982
      sb.append("<home_server>");
983
      sb.append(doc.getDocHomeServer());
984
      sb.append("</home_server>");
985
      sb.append("<public_access>").append(doc.getPublicaccess());
986
      sb.append("</public_access><rev>").append(doc.getRev());
987
      sb.append("</rev>");
988
      
989
      //permissions on the document
990
      PermissionController permController = new PermissionController(docid);
991
      Vector accessControlList = permController.getAccessControl();
992
      sb.append("<accessControl>");
993
      for (int i = 0; i < accessControlList.size(); i++) {
994
    	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
995
    	  sb.append(acfsf.getAccessString());
996
      }
997
      sb.append("</accessControl>");
998
      
999
      sb.append("</documentinfo>");
1000
      response.setContentType("text/xml");
1001
      out.println(sb.toString());
1002

    
1003
    }
1004
    catch (Exception e)
1005
    {
1006
      System.out.println("error in " +
1007
                         "metacatReplication.handlegetdocumentinforequest: " +
1008
                          e.getMessage());
1009
    }
1010

    
1011
  }
1012

    
1013
  /**
1014
   * Sends a datafile to a remote host
1015
   */
1016
  private void handleGetDataFileRequest(OutputStream outPut,
1017
                            Hashtable params, HttpServletResponse response)
1018

    
1019
  {
1020
    // File path for data file
1021
    String filepath;
1022
    // Request docid
1023
    String docId = ((String[])(params.get("docid")))[0];
1024
    //check if the doicd is null
1025
    if (docId==null)
1026
    {
1027
      logMetacat.error("Didn't specify docid for replication");
1028
      return;
1029
    }
1030

    
1031
    //try to open a https stream to test if the request server's public key
1032
    //in the key store, this is security issue
1033
    try
1034
    {
1035
      filepath = PropertyService.getProperty("application.datafilepath");
1036
      String server = ((String[])params.get("server"))[0];
1037
      URL u = new URL("https://" + server + "?server="
1038
                +MetaCatUtil.getLocalReplicationServerName()
1039
                +"&action=test");
1040
      String test = MetacatReplication.getURLContent(u);
1041
      //couldn't pass the test
1042
      if (test.indexOf("successfully")==-1)
1043
      {
1044
        //response.setContentType("text/xml");
1045
        //outPut.println("<error>Couldn't pass the trust test</error>");
1046
        logMetacat.error("Couldn't pass the trust test");
1047
        return;
1048
      }
1049
    }//try
1050
    catch (Exception ee)
1051
    {
1052
      return;
1053
    }//catch
1054

    
1055
    if(!filepath.endsWith("/"))
1056
    {
1057
          filepath += "/";
1058
    }
1059
    // Get file aboslute file name
1060
    String filename = filepath + docId;
1061

    
1062
    //MIME type
1063
    String contentType = null;
1064
    if (filename.endsWith(".xml"))
1065
    {
1066
        contentType="text/xml";
1067
    }
1068
    else if (filename.endsWith(".css"))
1069
    {
1070
        contentType="text/css";
1071
    }
1072
    else if (filename.endsWith(".dtd"))
1073
    {
1074
        contentType="text/plain";
1075
    }
1076
    else if (filename.endsWith(".xsd"))
1077
    {
1078
        contentType="text/xml";
1079
    }
1080
    else if (filename.endsWith("/"))
1081
    {
1082
        contentType="text/html";
1083
    }
1084
    else
1085
    {
1086
        File f = new File(filename);
1087
        if ( f.isDirectory() )
1088
        {
1089
           contentType="text/html";
1090
        }
1091
        else
1092
        {
1093
           contentType="application/octet-stream";
1094
        }
1095
     }
1096

    
1097
   // Set the mime type
1098
   response.setContentType(contentType);
1099

    
1100
   // Get the content of the file
1101
   FileInputStream fin = null;
1102
   try
1103
   {
1104
      // FileInputStream to metacat
1105
      fin = new FileInputStream(filename);
1106
      // 4K buffer
1107
      byte[] buf = new byte[4 * 1024];
1108
      // Read data from file input stream to byte array
1109
      int b = fin.read(buf);
1110
      // Write to outStream from byte array
1111
      while (b != -1)
1112
      {
1113
        outPut.write(buf, 0, b);
1114
        b = fin.read(buf);
1115
      }
1116
      // close file input stream
1117
      fin.close();
1118

    
1119
   }//try
1120
   catch(Exception e)
1121
   {
1122
      System.out.println("error getting data file from MetacatReplication." +
1123
                         "handlGetDataFileRequest " + e.getMessage());
1124
      e.printStackTrace(System.out);
1125
   }//catch
1126

    
1127
}
1128

    
1129

    
1130
  /**
1131
   * Sends a document to a remote host
1132
   */
1133
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params,
1134
                                        HttpServletResponse response)
1135
  {
1136

    
1137
    try
1138
    {
1139
      //try to open a https stream to test if the request server's public key
1140
      //in the key store, this is security issue
1141
      String server = ((String[])params.get("server"))[0];
1142
      URL u = new URL("https://" + server + "?server="
1143
                +MetaCatUtil.getLocalReplicationServerName()
1144
                +"&action=test");
1145
      String test = MetacatReplication.getURLContent(u);
1146
      //couldn't pass the test
1147
      if (test.indexOf("successfully")==-1)
1148
      {
1149
        response.setContentType("text/xml");
1150
        out.println("<error>Couldn't pass the trust test "+test+" </error>");
1151
        out.close();
1152
        return;
1153
      }
1154

    
1155
      String docid = ((String[])(params.get("docid")))[0];
1156

    
1157
      DocumentImpl di = new DocumentImpl(docid);
1158
      response.setContentType("text/xml");
1159
      out.print(di.toString(null, null, true));
1160

    
1161
      MetacatReplication.replLog("document " + docid + " sent");
1162

    
1163
    }
1164
    catch(Exception e)
1165
    {
1166
      logMetacat.error("error getting document from MetacatReplication."
1167
                          +"handlGetDocumentRequest " + e.getMessage());
1168
      //e.printStackTrace(System.out);
1169
      response.setContentType("text/xml");
1170
      out.println("<error>"+e.getMessage()+"</error>");
1171
    }
1172

    
1173
  }
1174

    
1175
  /**
1176
   * Sends a list of all of the documents on this sever along with their
1177
   * revision numbers.
1178
   * The format is:
1179
   * <!ELEMENT replication (server, updates)>
1180
   * <!ELEMENT server (#PCDATA)>
1181
   * <!ELEMENT updates ((updatedDocument | deleteDocument | revisionDocument)*)>
1182
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
1183
   * <!ELEMENT deletedDocument (docid, rev)>
1184
   * <!ELEMENT revisionDocument (docid, rev, datafile*)>
1185
   * <!ELEMENT docid (#PCDATA)>
1186
   * <!ELEMENT rev (#PCDATA)>
1187
   * <!ELEMENT datafile (#PCDATA)>
1188
   * note that the rev in deletedDocument is always empty.  I just left
1189
   * it in there to make the parser implementation easier.
1190
   */
1191
  private void handleUpdateRequest(PrintWriter out, Hashtable params,
1192
                                    HttpServletResponse response)
1193
  {
1194
    // Checked out DBConnection
1195
    DBConnection dbConn = null;
1196
    // DBConenction serial number when checked it out
1197
    int serialNumber = -1;
1198
    PreparedStatement pstmt = null;
1199
    // Server list to store server info of xml_replication table
1200
    ReplicationServerList serverList = null;
1201

    
1202
    try
1203
    {
1204
      // Check out a DBConnection from pool
1205
      dbConn=DBConnectionPool.
1206
                  getDBConnection("MetacatReplication.handleUpdateRequest");
1207
      serialNumber=dbConn.getCheckOutSerialNumber();
1208
      // Create a server list from xml_replication table
1209
      serverList = new ReplicationServerList();
1210

    
1211
      // Get remote server name from param
1212
      String server = ((String[])params.get("server"))[0];
1213
      // If no servr name in param, return a error
1214
      if ( server == null || server.equals(""))
1215
      {
1216
        response.setContentType("text/xml");
1217
        out.println("<error>Request didn't specify server name</error>");
1218
        out.close();
1219
        return;
1220
      }//if
1221

    
1222
      //try to open a https stream to test if the request server's public key
1223
      //in the key store, this is security issue
1224
      URL u = new URL("https://" + server + "?server="
1225
                +MetaCatUtil.getLocalReplicationServerName()
1226
                +"&action=test");
1227
      String test = MetacatReplication.getURLContent(u);
1228
      //couldn't pass the test
1229
      if (test.indexOf("successfully")==-1)
1230
      {
1231
        response.setContentType("text/xml");
1232
        out.println("<error>Couldn't pass the trust test</error>");
1233
        out.close();
1234
        return;
1235
      }
1236

    
1237

    
1238
      // Check if local host configure to replicate xml documents to remote
1239
      // server. If not send back a error message
1240
      if (!serverList.getReplicationValue(server))
1241
      {
1242
        response.setContentType("text/xml");
1243
        out.println
1244
        ("<error>Configuration not allow to replicate document to you</error>");
1245
        out.close();
1246
        return;
1247
      }//if
1248

    
1249
      // Store the sql command
1250
      StringBuffer docsql = new StringBuffer();
1251
      StringBuffer revisionSql = new StringBuffer();
1252
      // Stroe the docid list
1253
      StringBuffer doclist = new StringBuffer();
1254
      // Store the deleted docid list
1255
      StringBuffer delsql = new StringBuffer();
1256
      // Store the data set file
1257
      Vector packageFiles = new Vector();
1258

    
1259
      // Append local server's name and replication servlet to doclist
1260
      doclist.append("<?xml version=\"1.0\"?><replication>");
1261
      doclist.append("<server>").append(MetaCatUtil.getLocalReplicationServerName());
1262
      //doclist.append(util.getProperty("replicationpath"));
1263
      doclist.append("</server><updates>");
1264

    
1265
      // Get correct docid that reside on this server according the requesting
1266
      // server's replicate and data replicate value in xml_replication table
1267
      docsql.append(DatabaseService.getDBAdapter().getReplicationDocumentListSQL());
1268
      //docsql.append("select docid, rev, doctype from xml_documents where (docid not in (select a.docid from xml_documents a, xml_revisions b where a.docid=b.docid and a.rev<=b.rev)) ");
1269
      revisionSql.append("select docid, rev, doctype from xml_revisions ");
1270
      // If the localhost is not a hub to the remote server, only replicate
1271
      // the docid' which home server is local host (server_location =1)
1272
      if (!serverList.getHubValue(server))
1273
      {
1274
    	String serverLocationDoc = " and a.server_location = 1";
1275
        String serverLocationRev = "where server_location = 1";
1276
        docsql.append(serverLocationDoc);
1277
        revisionSql.append(serverLocationRev);
1278
      }
1279
      logMetacat.info("Doc sql: "+docsql.toString());
1280

    
1281
      // Get any deleted documents
1282
      delsql.append("select distinct docid from ");
1283
      delsql.append("xml_revisions where docid not in (select docid from ");
1284
      delsql.append("xml_documents) ");
1285
      // If the localhost is not a hub to the remote server, only replicate
1286
      // the docid' which home server is local host (server_location =1)
1287
      if (!serverList.getHubValue(server))
1288
      {
1289
        delsql.append("and server_location = 1");
1290
      }
1291
      logMetacat.info("Deleted sql: "+delsql.toString());
1292

    
1293

    
1294

    
1295
      // Get docid list of local host
1296
      pstmt = dbConn.prepareStatement(docsql.toString());
1297
      pstmt.execute();
1298
      ResultSet rs = pstmt.getResultSet();
1299
      boolean tablehasrows = rs.next();
1300
      //If metacat configed to replicate data file
1301
      //if ((util.getProperty("replicationsenddata")).equals("on"))
1302
      boolean replicateData = serverList.getDataReplicationValue(server);
1303
      if (replicateData)
1304
      {
1305
        while(tablehasrows)
1306
        {
1307
          String recordDoctype = rs.getString(3);
1308
          Vector packagedoctypes = MetaCatUtil.getOptionList(
1309
                                     PropertyService.getProperty("xml.packagedoctype"));
1310
          //if this is a package file, put it at the end
1311
          //because if a package file is read before all of the files it
1312
          //refers to are loaded then there is an error
1313
          if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1314
          {
1315
              //If this is not data file
1316
              if (!recordDoctype.equals("BIN"))
1317
              {
1318
                //for non-data file document
1319
                doclist.append("<updatedDocument>");
1320
                doclist.append("<docid>").append(rs.getString(1));
1321
                doclist.append("</docid><rev>").append(rs.getInt(2));
1322
                doclist.append("</rev>");
1323
                doclist.append("</updatedDocument>");
1324
              }//if
1325
              else
1326
              {
1327
                //for data file document, in datafile attributes
1328
                //we put "datafile" value there
1329
                doclist.append("<updatedDocument>");
1330
                doclist.append("<docid>").append(rs.getString(1));
1331
                doclist.append("</docid><rev>").append(rs.getInt(2));
1332
                doclist.append("</rev>");
1333
                doclist.append("<datafile>");
1334
                doclist.append(PropertyService.getProperty("replication.datafileflag"));
1335
                doclist.append("</datafile>");
1336
                doclist.append("</updatedDocument>");
1337
              }//else
1338
          }//if packagedoctpes
1339
          else
1340
          { //the package files are saved to be put into the xml later.
1341
              Vector v = new Vector();
1342
              v.add(new String(rs.getString(1)));
1343
              v.add(new Integer(rs.getInt(2)));
1344
              packageFiles.add(new Vector(v));
1345
          }//esle
1346
          tablehasrows = rs.next();
1347
        }//while
1348
      }//if
1349
      else //metacat was configured not to send data file
1350
      {
1351
        while(tablehasrows)
1352
        {
1353
          String recordDoctype = rs.getString(3);
1354
          if(!recordDoctype.equals("BIN"))
1355
          { //don't replicate data files
1356
            Vector packagedoctypes = MetaCatUtil.getOptionList(
1357
                                     PropertyService.getProperty("xml.packagedoctype"));
1358
            if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1359
            {   //if this is a package file, put it at the end
1360
              //because if a package file is read before all of the files it
1361
              //refers to are loaded then there is an error
1362
              doclist.append("<updatedDocument>");
1363
              doclist.append("<docid>").append(rs.getString(1));
1364
              doclist.append("</docid><rev>").append(rs.getInt(2));
1365
              doclist.append("</rev>");
1366
              doclist.append("</updatedDocument>");
1367
            }
1368
            else
1369
            { //the package files are saved to be put into the xml later.
1370
              Vector v = new Vector();
1371
              v.add(new String(rs.getString(1)));
1372
              v.add(new Integer(rs.getInt(2)));
1373
              packageFiles.add(new Vector(v));
1374
            }
1375
         }//if
1376
         tablehasrows = rs.next();
1377
        }//while
1378
      }//else
1379

    
1380
      pstmt = dbConn.prepareStatement(delsql.toString());
1381
      //usage count should increas 1
1382
      dbConn.increaseUsageCount(1);
1383

    
1384
      pstmt.execute();
1385
      rs = pstmt.getResultSet();
1386
      tablehasrows = rs.next();
1387
      while(tablehasrows)
1388
      { //handle the deleted documents
1389
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1390
        doclist.append("</docid><rev></rev></deletedDocument>");
1391
        //note that rev is always empty for deleted docs
1392
        tablehasrows = rs.next();
1393
      }
1394

    
1395
      //now we can put the package files into the xml results
1396
      for(int i=0; i<packageFiles.size(); i++)
1397
      {
1398
        Vector v = (Vector)packageFiles.elementAt(i);
1399
        doclist.append("<updatedDocument>");
1400
        doclist.append("<docid>").append((String)v.elementAt(0));
1401
        doclist.append("</docid><rev>");
1402
        doclist.append(((Integer)v.elementAt(1)).intValue());
1403
        doclist.append("</rev>");
1404
        doclist.append("</updatedDocument>");
1405
      }
1406
      // add revision doc list  
1407
      doclist.append(prepareRevisionDoc(dbConn,revisionSql.toString(),replicateData));
1408
        
1409
      doclist.append("</updates></replication>");
1410
      logMetacat.info("doclist: " + doclist.toString());
1411
      pstmt.close();
1412
      //conn.close();
1413
      response.setContentType("text/xml");
1414
      out.println(doclist.toString());
1415

    
1416
    }
1417
    catch(Exception e)
1418
    {
1419
      logMetacat.error("error in MetacatReplication." +
1420
                         "handleupdaterequest: " + e.getMessage());
1421
      //e.printStackTrace(System.out);
1422
      response.setContentType("text/xml");
1423
      out.println("<error>"+e.getMessage()+"</error>");
1424
    }
1425
    finally
1426
    {
1427
      try
1428
      {
1429
        pstmt.close();
1430
      }//try
1431
      catch (SQLException ee)
1432
      {
1433
        logMetacat.error("Error in MetacatReplication." +
1434
                "handleUpdaterequest to close pstmt: "+ee.getMessage());
1435
      }//catch
1436
      finally
1437
      {
1438
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1439
      }//finally
1440
    }//finally
1441

    
1442
  }//handlUpdateRequest
1443
  
1444
  /*
1445
   * This method will get the xml string for document in xml_revision
1446
   * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1447
   */
1448
  private String prepareRevisionDoc(DBConnection dbConn, String revSql, 
1449
                            boolean replicateData) throws Exception
1450
  {
1451
      logMetacat.warn("The revision document sql is "+ revSql);
1452
      StringBuffer revDocList = new StringBuffer();
1453
      PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1454
      //usage count should increas 1
1455
      dbConn.increaseUsageCount(1);
1456

    
1457
      pstmt.execute();
1458
      ResultSet rs = pstmt.getResultSet();
1459
      boolean tablehasrows = rs.next();
1460
      while(tablehasrows)
1461
      {
1462
        String recordDoctype = rs.getString(3);
1463
        
1464
        //If this is data file and it isn't configured to replicate data
1465
        if (recordDoctype.equals("BIN") && !replicateData)
1466
        {  
1467
            // do nothing
1468
            continue;
1469
        }
1470
        else
1471
        {  
1472
            
1473
            revDocList.append("<revisionDocument>");
1474
            revDocList.append("<docid>").append(rs.getString(1));
1475
            revDocList.append("</docid><rev>").append(rs.getInt(2));
1476
            revDocList.append("</rev>");
1477
            // data file
1478
            if (recordDoctype.equals("BIN"))
1479
            {
1480
                revDocList.append("<datafile>");
1481
                revDocList.append(PropertyService.getProperty("replication.datafileflag"));
1482
                revDocList.append("</datafile>");
1483
            }
1484
            revDocList.append("</revisionDocument>");
1485
        
1486
         }//else
1487
         tablehasrows = rs.next();
1488
      }
1489
      //System.out.println("The revision list is"+ revDocList.toString());
1490
      return revDocList.toString();
1491
  }
1492

    
1493
  /**
1494
   * Returns the xml_catalog table encoded in xml
1495
   */
1496
  public static String getCatalogXML()
1497
  {
1498
    return handleGetCatalogRequest(null, null, null, false);
1499
  }
1500

    
1501
  /**
1502
   * Sends the contents of the xml_catalog table encoded in xml
1503
   * The xml format is:
1504
   * <!ELEMENT xml_catalog (row*)>
1505
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1506
   *                system_id)>
1507
   * All of the sub elements of row are #PCDATA
1508

    
1509
   * If printFlag == false then do not print to out.
1510
   */
1511
  private static String handleGetCatalogRequest(PrintWriter out,
1512
                                                Hashtable params,
1513
                                                HttpServletResponse response,
1514
                                                boolean printFlag)
1515
  {
1516
    DBConnection dbConn = null;
1517
    int serialNumber = -1;
1518
    PreparedStatement pstmt = null;
1519
    try
1520
    {
1521
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1522
                                                "handleGetCatalogRequest");*/
1523
      dbConn=DBConnectionPool.
1524
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1525
      serialNumber=dbConn.getCheckOutSerialNumber();
1526
      pstmt = dbConn.prepareStatement("select entry_type, " +
1527
                              "source_doctype, target_doctype, public_id, " +
1528
                              "system_id from xml_catalog");
1529
      pstmt.execute();
1530
      ResultSet rs = pstmt.getResultSet();
1531
      boolean tablehasrows = rs.next();
1532
      StringBuffer sb = new StringBuffer();
1533
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1534
      while(tablehasrows)
1535
      {
1536
        sb.append("<row><entry_type>").append(rs.getString(1));
1537
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1538
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1539
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1540
        // system id may not have server url on front.  Add it if not.
1541
        String systemID = rs.getString(5);
1542
        if (!systemID.startsWith("http://")) {
1543
        	systemID = SystemUtil.getContextURL() + systemID;
1544
        }
1545
        sb.append("</public_id><system_id>").append(systemID);
1546
        sb.append("</system_id></row>");
1547

    
1548
        tablehasrows = rs.next();
1549
      }
1550
      sb.append("</xml_catalog>");
1551
      //conn.close();
1552
      if(printFlag)
1553
      {
1554
        response.setContentType("text/xml");
1555
        out.println(sb.toString());
1556
      }
1557
      pstmt.close();
1558
      return sb.toString();
1559
    }
1560
    catch(Exception e)
1561
    {
1562

    
1563
      logMetacat.error("error in MetacatReplication.handleGetCatalogRequest:"+
1564
                          e.getMessage());
1565
      e.printStackTrace(System.out);
1566
      if(printFlag)
1567
      {
1568
        out.println("<error>"+e.getMessage()+"</error>");
1569
      }
1570
    }
1571
    finally
1572
    {
1573
      try
1574
      {
1575
        pstmt.close();
1576
      }//try
1577
      catch (SQLException ee)
1578
      {
1579
        logMetacat.error("Error in MetacatReplication.handleGetCatalogRequest: "
1580
           +ee.getMessage());
1581
      }//catch
1582
      finally
1583
      {
1584
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1585
      }//finally
1586
    }//finally
1587

    
1588
    return null;
1589
  }
1590

    
1591
  /**
1592
   * Sends the current system date to the remote server.  Using this action
1593
   * for replication gets rid of any problems with syncronizing clocks
1594
   * because a time specific to a document is always kept on its home server.
1595
   */
1596
  private void handleGetTimeRequest(PrintWriter out, Hashtable params,
1597
                                    HttpServletResponse response)
1598
  {
1599
    SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yy HH:mm:ss");
1600
    java.util.Date localtime = new java.util.Date();
1601
    String dateString = formatter.format(localtime);
1602
    response.setContentType("text/xml");
1603

    
1604
    out.println("<timestamp>" + dateString + "</timestamp>");
1605
  }
1606

    
1607
  /**
1608
   * this method handles the timeout for a file lock.  when a lock is
1609
   * granted it is granted for 30 seconds.  When this thread runs out
1610
   * it deletes the docid from the queue, thus eliminating the lock.
1611
   */
1612
  public void run()
1613
  {
1614
    try
1615
    {
1616
      logMetacat.info("thread started for docid: " +
1617
                               (String)fileLocks.elementAt(0));
1618

    
1619
      Thread.sleep(30000); //the lock will expire in 30 seconds
1620
      logMetacat.info("thread for docid: " +
1621
                             (String)fileLocks.elementAt(fileLocks.size() - 1) +
1622
                              " exiting.");
1623

    
1624
      fileLocks.remove(fileLocks.size() - 1);
1625
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1626
      //in the vector, the first one inserted will be removed.
1627
    }
1628
    catch(Exception e)
1629
    {
1630
      logMetacat.error("error in file lock thread from " +
1631
                                "MetacatReplication.run: " + e.getMessage());
1632
    }
1633
  }
1634

    
1635
  /**
1636
   * Returns the name of a server given a serverCode
1637
   * @param serverCode the serverid of the server
1638
   * @return the servername or null if the specified serverCode does not
1639
   *         exist.
1640
   */
1641
  public static String getServerNameForServerCode(int serverCode)
1642
  {
1643
    //System.out.println("serverid: " + serverCode);
1644
    DBConnection dbConn = null;
1645
    int serialNumber = -1;
1646
    PreparedStatement pstmt = null;
1647
    try
1648
    {
1649
      dbConn=DBConnectionPool.
1650
                  getDBConnection("MetacatReplication.getServer");
1651
      serialNumber=dbConn.getCheckOutSerialNumber();
1652
      String sql = new String("select server from " +
1653
                              "xml_replication where serverid = " +
1654
                              serverCode);
1655
      pstmt = dbConn.prepareStatement(sql);
1656
      //System.out.println("getserver sql: " + sql);
1657
      pstmt.execute();
1658
      ResultSet rs = pstmt.getResultSet();
1659
      boolean tablehasrows = rs.next();
1660
      if(tablehasrows)
1661
      {
1662
        //System.out.println("server: " + rs.getString(1));
1663
        return rs.getString(1);
1664
      }
1665

    
1666
      //conn.close();
1667
    }
1668
    catch(Exception e)
1669
    {
1670
      System.out.println("Error in MetacatReplication.getServer: " +
1671
                          e.getMessage());
1672
    }
1673
    finally
1674
    {
1675
      try
1676
      {
1677
        pstmt.close();
1678
      }//try
1679
      catch (SQLException ee)
1680
      {
1681
        logMetacat.error("Error in MetacactReplication.getserver: "+
1682
                                    ee.getMessage());
1683
      }//catch
1684
      finally
1685
      {
1686
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1687
      }//fianlly
1688
    }//finally
1689

    
1690

    
1691

    
1692
    return null;
1693
      //return null if the server does not exist
1694
  }
1695

    
1696
  /**
1697
   * Returns a server code given a server name
1698
   * @param server the name of the server
1699
   * @return integer > 0 representing the code of the server, 0 if the server
1700
   *  does not exist.
1701
   */
1702
  public static int getServerCodeForServerName(String server) throws Exception
1703
  {
1704
    DBConnection dbConn = null;
1705
    int serialNumber = -1;
1706
    PreparedStatement pstmt = null;
1707
    int serverCode = 0;
1708

    
1709
    try {
1710

    
1711
      //conn = util.openDBConnection();
1712
      dbConn=DBConnectionPool.
1713
                  getDBConnection("MetacatReplication.getServerCode");
1714
      serialNumber=dbConn.getCheckOutSerialNumber();
1715
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1716
                                    "WHERE server LIKE '" + server + "'");
1717
      pstmt.execute();
1718
      ResultSet rs = pstmt.getResultSet();
1719
      boolean tablehasrows = rs.next();
1720
      if ( tablehasrows ) {
1721
        serverCode = rs.getInt(1);
1722
        pstmt.close();
1723
        //conn.close();
1724
        return serverCode;
1725
      }
1726

    
1727
    } catch(Exception e) {
1728
      throw e;
1729

    
1730
    } finally {
1731
      try
1732
      {
1733
        pstmt.close();
1734
        //conn.close();
1735
       }//try
1736
       catch(Exception ee)
1737
       {
1738
         logMetacat.error("Error in MetacatReplicatio.getServerCode: "
1739
                                  +ee.getMessage());
1740

    
1741
       }//catch
1742
       finally
1743
       {
1744
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1745
       }//finally
1746
    }//finally
1747

    
1748
    return serverCode;
1749
  }
1750

    
1751
  /**
1752
   * Method to get a host server information for given docid
1753
   * @param conn a connection to the database
1754
   */
1755
  public static Hashtable getHomeServerInfoForDocId(String docId)
1756
  {
1757
    Hashtable sl = new Hashtable();
1758
    DBConnection dbConn = null;
1759
    int serialNumber = -1;
1760
    docId=MetaCatUtil.getDocIdFromString(docId);
1761
    PreparedStatement pstmt=null;
1762
    int serverLocation;
1763
    try
1764
    {
1765
      //get conection
1766
      dbConn=DBConnectionPool.
1767
                  getDBConnection("ReplicationHandler.getHomeServer");
1768
      serialNumber=dbConn.getCheckOutSerialNumber();
1769
      //get a server location from xml_document table
1770
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
1771
                                            +"where docid = ?");
1772
      pstmt.setString(1, docId);
1773
      pstmt.execute();
1774
      ResultSet serverName = pstmt.getResultSet();
1775
      //get a server location
1776
      if(serverName.next())
1777
      {
1778
        serverLocation=serverName.getInt(1);
1779
        pstmt.close();
1780
      }
1781
      else
1782
      {
1783
        pstmt.close();
1784
        //ut.returnConnection(conn);
1785
        return null;
1786
      }
1787
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
1788
                        "from xml_replication where serverid = ?");
1789
      //increase usage count
1790
      dbConn.increaseUsageCount(1);
1791
      pstmt.setInt(1, serverLocation);
1792
      pstmt.execute();
1793
      ResultSet rs = pstmt.getResultSet();
1794
      boolean tableHasRows = rs.next();
1795
      if (tableHasRows)
1796
      {
1797

    
1798
          String server = rs.getString(1);
1799
          String last_checked = rs.getString(2);
1800
          if(!server.equals("localhost"))
1801
          {
1802
            sl.put(server, last_checked);
1803
          }
1804

    
1805
      }
1806
      else
1807
      {
1808
        pstmt.close();
1809
        //ut.returnConnection(conn);
1810
        return null;
1811
      }
1812
      pstmt.close();
1813
    }
1814
    catch(Exception e)
1815
    {
1816
      System.out.println("error in replicationHandler.getHomeServer(): " +
1817
                         e.getMessage());
1818
    }
1819
    finally
1820
    {
1821
      try
1822
      {
1823
        pstmt.close();
1824
        //ut.returnConnection(conn);
1825
      }
1826
      catch (Exception ee)
1827
      {
1828
        logMetacat.error("Eror irn rplicationHandler.getHomeServer() "+
1829
                          "to close pstmt: "+ee.getMessage());
1830
      }
1831
      finally
1832
      {
1833
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1834
      }
1835

    
1836
    }//finally
1837
    return sl;
1838
  }
1839

    
1840
  /**
1841
   * Returns a home server location  given a accnum
1842
   * @param accNum , given accNum for a document
1843
   *
1844
   */
1845
  public static int getHomeServerCodeForDocId(String accNum) throws Exception
1846
  {
1847
    DBConnection dbConn = null;
1848
    int serialNumber = -1;
1849
    PreparedStatement pstmt = null;
1850
    int serverCode = 1;
1851
    String docId=MetaCatUtil.getDocIdFromString(accNum);
1852

    
1853
    try
1854
    {
1855

    
1856
      // Get DBConnection
1857
      dbConn=DBConnectionPool.
1858
                  getDBConnection("ReplicationHandler.getServerLocation");
1859
      serialNumber=dbConn.getCheckOutSerialNumber();
1860
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1861
                              + "WHERE docid LIKE '" + docId + "'");
1862
      pstmt.execute();
1863
      ResultSet rs = pstmt.getResultSet();
1864
      boolean tablehasrows = rs.next();
1865
      //If a document is find, return the server location for it
1866
      if ( tablehasrows )
1867
      {
1868
        serverCode = rs.getInt(1);
1869
        pstmt.close();
1870
        //conn.close();
1871
        return serverCode;
1872
      }
1873
      //if couldn't find in xml_documents table, we think server code is 1
1874
      //(this is new document)
1875
      else
1876
      {
1877
        pstmt.close();
1878
        //conn.close();
1879
        return serverCode;
1880
      }
1881

    
1882
    }
1883
    catch(Exception e)
1884
    {
1885

    
1886
      throw e;
1887

    
1888
    }
1889
    finally
1890
    {
1891
      try
1892
      {
1893
        pstmt.close();
1894
        //conn.close();
1895

    
1896
      }
1897
      catch(Exception ee)
1898
      {
1899
        logMetacat.error("Erorr in Replication.getServerLocation "+
1900
                     "to close pstmt"+ee.getMessage());
1901
      }
1902
      finally
1903
      {
1904
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1905
      }//finally
1906
    }//finally
1907
   //return serverCode;
1908
  }
1909

    
1910

    
1911

    
1912
  /**
1913
   * This method returns the content of a url
1914
   * @param u the url to return the content from
1915
   * @return a string representing the content of the url
1916
   * @throws java.io.IOException
1917
   */
1918
  public static String getURLContent(URL u) throws java.io.IOException
1919
  {
1920
    char istreamChar;
1921
    int istreamInt;
1922
    logMetacat.info("Before open the stream"+u.toString());
1923
    InputStream input = u.openStream();
1924
    logMetacat.info("Afetr open the stream"+u.toString());
1925
    InputStreamReader istream = new InputStreamReader(input);
1926
    StringBuffer serverResponse = new StringBuffer();
1927
    while((istreamInt = istream.read()) != -1)
1928
    {
1929
      istreamChar = (char)istreamInt;
1930
      serverResponse.append(istreamChar);
1931
    }
1932
    istream.close();
1933
    input.close();
1934

    
1935
    return serverResponse.toString();
1936
  }
1937

    
1938
  /**
1939
	 * Method for writing replication messages to a log file specified in
1940
	 * metacat.properties
1941
	 */
1942
	public static void replLog(String message) {
1943
		try {
1944
			FileOutputStream fos = 
1945
				new FileOutputStream(PropertyService.getProperty("replication.logdir")
1946
					+ "/metacatreplication.log", true);
1947
			PrintWriter pw = new PrintWriter(fos);
1948
			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
1949
			java.util.Date localtime = new java.util.Date();
1950
			String dateString = formatter.format(localtime);
1951
			dateString += " :: " + message;
1952
			// time stamp each entry
1953
			pw.println(dateString);
1954
			pw.flush();
1955
		} catch (Exception e) {
1956
			System.out.println("error writing to replication log from "
1957
					+ "MetacatReplication.replLog: " + e.getMessage());
1958
			// e.printStackTrace(System.out);
1959
		}
1960
	}
1961

    
1962
  /**
1963
	 * Method for writing replication messages to a log file specified in
1964
	 * metacat.properties
1965
	 */
1966
  public static void replErrorLog(String message)
1967
  {
1968
    try
1969
    {
1970
    	FileOutputStream fos = 
1971
			new FileOutputStream(PropertyService.getProperty("replication.logdir")
1972
				+ "/metacatreplicationerror.log", true);
1973
      PrintWriter pw = new PrintWriter(fos);
1974
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1975
      java.util.Date localtime = new java.util.Date();
1976
      String dateString = formatter.format(localtime);
1977
      dateString += " :: " + message;
1978
      //time stamp each entry
1979
      pw.println(dateString);
1980
      pw.flush();
1981
    }
1982
    catch(Exception e)
1983
    {
1984
      System.out.println("error writing to replication error log from " +
1985
                         "MetacatReplication.replErrorLog: " + e.getMessage());
1986
      //e.printStackTrace(System.out);
1987
    }
1988
  }
1989

    
1990
  /**
1991
   * Returns true if the replicate field for server in xml_replication is 1.
1992
   * Returns false otherwise
1993
   */
1994
  public static boolean replToServer(String server)
1995
  {
1996
    DBConnection dbConn = null;
1997
    int serialNumber = -1;
1998
    PreparedStatement pstmt = null;
1999
    try
2000
    {
2001
      dbConn=DBConnectionPool.
2002
                  getDBConnection("MetacatReplication.repltoServer");
2003
      serialNumber=dbConn.getCheckOutSerialNumber();
2004
      pstmt = dbConn.prepareStatement("select replicate from " +
2005
                                    "xml_replication where server like '" +
2006
                                     server + "'");
2007
      pstmt.execute();
2008
      ResultSet rs = pstmt.getResultSet();
2009
      boolean tablehasrows = rs.next();
2010
      if(tablehasrows)
2011
      {
2012
        int i = rs.getInt(1);
2013
        if(i == 1)
2014
        {
2015
          pstmt.close();
2016
          //conn.close();
2017
          return true;
2018
        }
2019
        else
2020
        {
2021
          pstmt.close();
2022
          //conn.close();
2023
          return false;
2024
        }
2025
      }
2026
    }
2027
    catch(Exception e)
2028
    {
2029
      System.out.println("error in MetacatReplication.replToServer: " +
2030
                         e.getMessage());
2031
    }
2032
    finally
2033
    {
2034
      try
2035
      {
2036
        pstmt.close();
2037
        //conn.close();
2038
      }//try
2039
      catch(Exception ee)
2040
      {
2041
        logMetacat.error("Error in MetacatReplication.replToServer: "
2042
                                  +ee.getMessage());
2043
      }//catch
2044
      finally
2045
      {
2046
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2047
      }//finally
2048
    }//finally
2049
    return false;
2050
    //the default if this server does not exist is to not replicate to it.
2051
  }
2052

    
2053

    
2054
}
(46-46/67)