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: daigle $'
9
 *     '$Date: 2008-11-19 15:25:09 -0800 (Wed, 19 Nov 2008) $'
10
 * '$Revision: 4589 $'
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.AuthUtil;
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.FileUtil;
47
import edu.ucsb.nceas.utilities.GeneralPropertyException;
48
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
49

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

    
53
public class MetacatReplication extends HttpServlet implements Runnable
54
{
55

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

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

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

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

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

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

    
144

    
145

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

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

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

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

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

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

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

    
259

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

    
319

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
537
  }
538

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

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

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

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

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

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

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

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

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

    
640
      //dih is the parser for the docinfo xml format
641
      DocInfoHandler dih = new DocInfoHandler();
642
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
643
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
644
//      Hashtable<String,Vector<AccessControlForSingleFile>> docinfoHash = dih.getDocInfo();
645
      Hashtable<String,String> docinfoHash = dih.getDocInfo();
646

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

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

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

    
723
    }//catch
724
    finally
725
    {
726
      // Return the checked out DBConnection
727
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
728
    }//finally
729
  }
730

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

    
759
  }//catch
760

    
761
}
762

    
763

    
764
  /**
765
   * when a forcereplication data file request comes in, local host sends a
766
   * readdata request to the requesting server (remote server) for the specified
767
   * docid. Then store it in local database and file system
768
   */
769
  private void handleForceReplicateDataFileRequest(Hashtable<String, String[]> params, HttpServletRequest request)
770
  {
771

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

    
788
    // Overide or not
789
//    boolean override = false;
790
    // dbaction - update or insert
791
    String dbaction=null;
792

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

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

    
816
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
817

    
818
      //dih is the parser for the docinfo xml format
819
      DocInfoHandler dih = new DocInfoHandler();
820
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
821
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
822
      Hashtable<String,String> docinfoHash = dih.getDocInfo();
823
      String user = (String)docinfoHash.get("user_owner");
824

    
825
      String docName = (String)docinfoHash.get("docname");
826

    
827
      String docType = (String)docinfoHash.get("doctype");
828

    
829
      String docHomeServer= (String)docinfoHash.get("home_server");
830
      
831
      String createdDate = (String)docinfoHash.get("date_created");
832
      
833
      String updatedDate = (String)docinfoHash.get("date_updated");
834
      logMetacat.info("docHomeServer of datafile: "+docHomeServer);
835

    
836

    
837

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

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

    
913
    try
914
    {
915

    
916
      String docid = ((String[])params.get("docid"))[0];
917
      String remoteRev = ((String[])params.get("updaterev"))[0];
918
      DocumentImpl requestDoc = new DocumentImpl(docid);
919
      MetacatReplication.replLog("lock request for " + docid);
920
      int localRevInt = requestDoc.getRev();
921
      int remoteRevInt = Integer.parseInt(remoteRev);
922

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

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

    
971
    try
972
    {
973

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

    
1009
    }
1010
    catch (Exception e)
1011
    {
1012
      System.out.println("error in " +
1013
                         "metacatReplication.handlegetdocumentinforequest: " +
1014
                          e.getMessage());
1015
    }
1016

    
1017
  }
1018

    
1019
  /**
1020
   * Sends a datafile to a remote host
1021
   */
1022
  private void handleGetDataFileRequest(OutputStream outPut,
1023
                            Hashtable<String, String[]> params, HttpServletResponse response)
1024

    
1025
  {
1026
    // File path for data file
1027
    String filepath;
1028
    // Request docid
1029
    String docId = ((String[])(params.get("docid")))[0];
1030
    //check if the doicd is null
1031
    if (docId==null)
1032
    {
1033
      logMetacat.error("Didn't specify docid for replication");
1034
      return;
1035
    }
1036

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

    
1061
    if(!filepath.endsWith("/"))
1062
    {
1063
          filepath += "/";
1064
    }
1065
    // Get file aboslute file name
1066
    String filename = filepath + docId;
1067

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

    
1103
   // Set the mime type
1104
   response.setContentType(contentType);
1105

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

    
1125
   }//try
1126
   catch(Exception e)
1127
   {
1128
      System.out.println("error getting data file from MetacatReplication." +
1129
                         "handlGetDataFileRequest " + e.getMessage());
1130
      e.printStackTrace(System.out);
1131
   }//catch
1132

    
1133
}
1134

    
1135

    
1136
  /**
1137
   * Sends a document to a remote host
1138
   */
1139
  private void handleGetDocumentRequest(PrintWriter out, Hashtable<String, String[]> params,
1140
                                        HttpServletResponse response)
1141
  {
1142

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

    
1161
      String docid = params.get("docid")[0];
1162
      DocumentImpl di = new DocumentImpl(docid);
1163
      
1164
      String documentDir = PropertyService.getProperty("application.documentfilepath");
1165
      String documentPath = documentDir + FileUtil.getFS() + docid;
1166
      
1167
      // if the document does not exist on disk, read it from db and write
1168
      // it to disk.
1169
	  if (FileUtil.getFileStatus(documentPath) == FileUtil.DOES_NOT_EXIST) {
1170
	    FileWriter fileWriter = new FileWriter(documentPath);
1171
		di.toXml(fileWriter, null, null, true);
1172
	  }
1173
		
1174
	  // read the file from disk and sent it to PrintWriter
1175
//		PrintWriter out = new PrintWriter(streamOut);
1176
	  di.readFromFileSystem(out, null, null, documentPath);
1177

    
1178
//      response.setContentType("text/xml");
1179
//      out.print(di.toString(null, null, true));
1180

    
1181
      MetacatReplication.replLog("document " + docid + " sent");
1182

    
1183
    }
1184
    catch(Exception e)
1185
    {
1186
      logMetacat.error("error getting document from MetacatReplication."
1187
                          +"handlGetDocumentRequest " + e.getMessage());
1188
      //e.printStackTrace(System.out);
1189
      response.setContentType("text/xml");
1190
      out.println("<error>"+e.getMessage()+"</error>");
1191
    }
1192

    
1193
  }
1194

    
1195
  /**
1196
   * Sends a list of all of the documents on this sever along with their
1197
   * revision numbers.
1198
   * The format is:
1199
   * <!ELEMENT replication (server, updates)>
1200
   * <!ELEMENT server (#PCDATA)>
1201
   * <!ELEMENT updates ((updatedDocument | deleteDocument | revisionDocument)*)>
1202
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
1203
   * <!ELEMENT deletedDocument (docid, rev)>
1204
   * <!ELEMENT revisionDocument (docid, rev, datafile*)>
1205
   * <!ELEMENT docid (#PCDATA)>
1206
   * <!ELEMENT rev (#PCDATA)>
1207
   * <!ELEMENT datafile (#PCDATA)>
1208
   * note that the rev in deletedDocument is always empty.  I just left
1209
   * it in there to make the parser implementation easier.
1210
   */
1211
  private void handleUpdateRequest(PrintWriter out, Hashtable<String, String[]> params,
1212
                                    HttpServletResponse response)
1213
  {
1214
    // Checked out DBConnection
1215
    DBConnection dbConn = null;
1216
    // DBConenction serial number when checked it out
1217
    int serialNumber = -1;
1218
    PreparedStatement pstmt = null;
1219
    // Server list to store server info of xml_replication table
1220
    ReplicationServerList serverList = null;
1221

    
1222
    try
1223
    {
1224
      // Check out a DBConnection from pool
1225
      dbConn=DBConnectionPool.
1226
                  getDBConnection("MetacatReplication.handleUpdateRequest");
1227
      serialNumber=dbConn.getCheckOutSerialNumber();
1228
      // Create a server list from xml_replication table
1229
      serverList = new ReplicationServerList();
1230

    
1231
      // Get remote server name from param
1232
      String server = ((String[])params.get("server"))[0];
1233
      // If no servr name in param, return a error
1234
      if ( server == null || server.equals(""))
1235
      {
1236
        response.setContentType("text/xml");
1237
        out.println("<error>Request didn't specify server name</error>");
1238
        out.close();
1239
        return;
1240
      }//if
1241

    
1242
      //try to open a https stream to test if the request server's public key
1243
      //in the key store, this is security issue
1244
      URL u = new URL("https://" + server + "?server="
1245
                +MetaCatUtil.getLocalReplicationServerName()
1246
                +"&action=test");
1247
      String test = MetacatReplication.getURLContent(u);
1248
      //couldn't pass the test
1249
      if (test.indexOf("successfully")==-1)
1250
      {
1251
        response.setContentType("text/xml");
1252
        out.println("<error>Couldn't pass the trust test</error>");
1253
        out.close();
1254
        return;
1255
      }
1256

    
1257

    
1258
      // Check if local host configure to replicate xml documents to remote
1259
      // server. If not send back a error message
1260
      if (!serverList.getReplicationValue(server))
1261
      {
1262
        response.setContentType("text/xml");
1263
        out.println
1264
        ("<error>Configuration not allow to replicate document to you</error>");
1265
        out.close();
1266
        return;
1267
      }//if
1268

    
1269
      // Store the sql command
1270
      StringBuffer docsql = new StringBuffer();
1271
      StringBuffer revisionSql = new StringBuffer();
1272
      // Stroe the docid list
1273
      StringBuffer doclist = new StringBuffer();
1274
      // Store the deleted docid list
1275
      StringBuffer delsql = new StringBuffer();
1276
      // Store the data set file
1277
      Vector<Vector<String>> packageFiles = new Vector<Vector<String>>();
1278

    
1279
      // Append local server's name and replication servlet to doclist
1280
      doclist.append("<?xml version=\"1.0\"?><replication>");
1281
      doclist.append("<server>").append(MetaCatUtil.getLocalReplicationServerName());
1282
      //doclist.append(util.getProperty("replicationpath"));
1283
      doclist.append("</server><updates>");
1284

    
1285
      // Get correct docid that reside on this server according the requesting
1286
      // server's replicate and data replicate value in xml_replication table
1287
      docsql.append(DatabaseService.getDBAdapter().getReplicationDocumentListSQL());
1288
      //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)) ");
1289
      revisionSql.append("select docid, rev, doctype from xml_revisions ");
1290
      // If the localhost is not a hub to the remote server, only replicate
1291
      // the docid' which home server is local host (server_location =1)
1292
      if (!serverList.getHubValue(server))
1293
      {
1294
    	String serverLocationDoc = " and a.server_location = 1";
1295
        String serverLocationRev = "where server_location = 1";
1296
        docsql.append(serverLocationDoc);
1297
        revisionSql.append(serverLocationRev);
1298
      }
1299
      logMetacat.info("Doc sql: "+docsql.toString());
1300

    
1301
      // Get any deleted documents
1302
      delsql.append("select distinct docid from ");
1303
      delsql.append("xml_revisions where docid not in (select docid from ");
1304
      delsql.append("xml_documents) ");
1305
      // If the localhost is not a hub to the remote server, only replicate
1306
      // the docid' which home server is local host (server_location =1)
1307
      if (!serverList.getHubValue(server))
1308
      {
1309
        delsql.append("and server_location = 1");
1310
      }
1311
      logMetacat.info("Deleted sql: "+delsql.toString());
1312

    
1313

    
1314

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

    
1400
      pstmt = dbConn.prepareStatement(delsql.toString());
1401
      //usage count should increas 1
1402
      dbConn.increaseUsageCount(1);
1403

    
1404
      pstmt.execute();
1405
      rs = pstmt.getResultSet();
1406
      tablehasrows = rs.next();
1407
      while(tablehasrows)
1408
      { //handle the deleted documents
1409
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1410
        doclist.append("</docid><rev></rev></deletedDocument>");
1411
        //note that rev is always empty for deleted docs
1412
        tablehasrows = rs.next();
1413
      }
1414

    
1415
      //now we can put the package files into the xml results
1416
      for(int i=0; i<packageFiles.size(); i++)
1417
      {
1418
        Vector<String> v = packageFiles.elementAt(i);
1419
        doclist.append("<updatedDocument>");
1420
        doclist.append("<docid>").append(v.elementAt(0));
1421
        doclist.append("</docid><rev>");
1422
        doclist.append(v.elementAt(1));
1423
        doclist.append("</rev>");
1424
        doclist.append("</updatedDocument>");
1425
      }
1426
      // add revision doc list  
1427
      doclist.append(prepareRevisionDoc(dbConn,revisionSql.toString(),replicateData));
1428
        
1429
      doclist.append("</updates></replication>");
1430
      logMetacat.info("doclist: " + doclist.toString());
1431
      pstmt.close();
1432
      //conn.close();
1433
      response.setContentType("text/xml");
1434
      out.println(doclist.toString());
1435

    
1436
    }
1437
    catch(Exception e)
1438
    {
1439
      logMetacat.error("error in MetacatReplication." +
1440
                         "handleupdaterequest: " + e.getMessage());
1441
      //e.printStackTrace(System.out);
1442
      response.setContentType("text/xml");
1443
      out.println("<error>"+e.getMessage()+"</error>");
1444
    }
1445
    finally
1446
    {
1447
      try
1448
      {
1449
        pstmt.close();
1450
      }//try
1451
      catch (SQLException ee)
1452
      {
1453
        logMetacat.error("Error in MetacatReplication." +
1454
                "handleUpdaterequest to close pstmt: "+ee.getMessage());
1455
      }//catch
1456
      finally
1457
      {
1458
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1459
      }//finally
1460
    }//finally
1461

    
1462
  }//handlUpdateRequest
1463
  
1464
  /*
1465
   * This method will get the xml string for document in xml_revision
1466
   * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1467
   */
1468
  private String prepareRevisionDoc(DBConnection dbConn, String revSql, 
1469
                            boolean replicateData) throws Exception
1470
  {
1471
      logMetacat.warn("The revision document sql is "+ revSql);
1472
      StringBuffer revDocList = new StringBuffer();
1473
      PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1474
      //usage count should increas 1
1475
      dbConn.increaseUsageCount(1);
1476

    
1477
      pstmt.execute();
1478
      ResultSet rs = pstmt.getResultSet();
1479
      boolean tablehasrows = rs.next();
1480
      while(tablehasrows)
1481
      {
1482
        String recordDoctype = rs.getString(3);
1483
        
1484
        //If this is data file and it isn't configured to replicate data
1485
        if (recordDoctype.equals("BIN") && !replicateData)
1486
        {  
1487
            // do nothing
1488
            continue;
1489
        }
1490
        else
1491
        {  
1492
            
1493
            revDocList.append("<revisionDocument>");
1494
            revDocList.append("<docid>").append(rs.getString(1));
1495
            revDocList.append("</docid><rev>").append(rs.getInt(2));
1496
            revDocList.append("</rev>");
1497
            // data file
1498
            if (recordDoctype.equals("BIN"))
1499
            {
1500
                revDocList.append("<datafile>");
1501
                revDocList.append(PropertyService.getProperty("replication.datafileflag"));
1502
                revDocList.append("</datafile>");
1503
            }
1504
            revDocList.append("</revisionDocument>");
1505
        
1506
         }//else
1507
         tablehasrows = rs.next();
1508
      }
1509
      //System.out.println("The revision list is"+ revDocList.toString());
1510
      return revDocList.toString();
1511
  }
1512

    
1513
  /**
1514
   * Returns the xml_catalog table encoded in xml
1515
   */
1516
  public static String getCatalogXML()
1517
  {
1518
    return handleGetCatalogRequest(null, null, null, false);
1519
  }
1520

    
1521
  /**
1522
   * Sends the contents of the xml_catalog table encoded in xml
1523
   * The xml format is:
1524
   * <!ELEMENT xml_catalog (row*)>
1525
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1526
   *                system_id)>
1527
   * All of the sub elements of row are #PCDATA
1528

    
1529
   * If printFlag == false then do not print to out.
1530
   */
1531
  private static String handleGetCatalogRequest(PrintWriter out,
1532
                                                Hashtable<String, String[]> params,
1533
                                                HttpServletResponse response,
1534
                                                boolean printFlag)
1535
  {
1536
    DBConnection dbConn = null;
1537
    int serialNumber = -1;
1538
    PreparedStatement pstmt = null;
1539
    try
1540
    {
1541
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1542
                                                "handleGetCatalogRequest");*/
1543
      dbConn=DBConnectionPool.
1544
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1545
      serialNumber=dbConn.getCheckOutSerialNumber();
1546
      pstmt = dbConn.prepareStatement("select entry_type, " +
1547
                              "source_doctype, target_doctype, public_id, " +
1548
                              "system_id from xml_catalog");
1549
      pstmt.execute();
1550
      ResultSet rs = pstmt.getResultSet();
1551
      boolean tablehasrows = rs.next();
1552
      StringBuffer sb = new StringBuffer();
1553
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1554
      while(tablehasrows)
1555
      {
1556
        sb.append("<row><entry_type>").append(rs.getString(1));
1557
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1558
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1559
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1560
        // system id may not have server url on front.  Add it if not.
1561
        String systemID = rs.getString(5);
1562
        if (!systemID.startsWith("http://")) {
1563
        	systemID = SystemUtil.getContextURL() + systemID;
1564
        }
1565
        sb.append("</public_id><system_id>").append(systemID);
1566
        sb.append("</system_id></row>");
1567

    
1568
        tablehasrows = rs.next();
1569
      }
1570
      sb.append("</xml_catalog>");
1571
      //conn.close();
1572
      if(printFlag)
1573
      {
1574
        response.setContentType("text/xml");
1575
        out.println(sb.toString());
1576
      }
1577
      pstmt.close();
1578
      return sb.toString();
1579
    }
1580
    catch(Exception e)
1581
    {
1582

    
1583
      logMetacat.error("error in MetacatReplication.handleGetCatalogRequest:"+
1584
                          e.getMessage());
1585
      e.printStackTrace(System.out);
1586
      if(printFlag)
1587
      {
1588
        out.println("<error>"+e.getMessage()+"</error>");
1589
      }
1590
    }
1591
    finally
1592
    {
1593
      try
1594
      {
1595
        pstmt.close();
1596
      }//try
1597
      catch (SQLException ee)
1598
      {
1599
        logMetacat.error("Error in MetacatReplication.handleGetCatalogRequest: "
1600
           +ee.getMessage());
1601
      }//catch
1602
      finally
1603
      {
1604
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1605
      }//finally
1606
    }//finally
1607

    
1608
    return null;
1609
  }
1610

    
1611
  /**
1612
   * Sends the current system date to the remote server.  Using this action
1613
   * for replication gets rid of any problems with syncronizing clocks
1614
   * because a time specific to a document is always kept on its home server.
1615
   */
1616
  private void handleGetTimeRequest(PrintWriter out, Hashtable<String, String[]> params,
1617
                                    HttpServletResponse response)
1618
  {
1619
    SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yy HH:mm:ss");
1620
    java.util.Date localtime = new java.util.Date();
1621
    String dateString = formatter.format(localtime);
1622
    response.setContentType("text/xml");
1623

    
1624
    out.println("<timestamp>" + dateString + "</timestamp>");
1625
  }
1626

    
1627
  /**
1628
   * this method handles the timeout for a file lock.  when a lock is
1629
   * granted it is granted for 30 seconds.  When this thread runs out
1630
   * it deletes the docid from the queue, thus eliminating the lock.
1631
   */
1632
  public void run()
1633
  {
1634
    try
1635
    {
1636
      logMetacat.info("thread started for docid: " +
1637
                               (String)fileLocks.elementAt(0));
1638

    
1639
      Thread.sleep(30000); //the lock will expire in 30 seconds
1640
      logMetacat.info("thread for docid: " +
1641
                             (String)fileLocks.elementAt(fileLocks.size() - 1) +
1642
                              " exiting.");
1643

    
1644
      fileLocks.remove(fileLocks.size() - 1);
1645
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1646
      //in the vector, the first one inserted will be removed.
1647
    }
1648
    catch(Exception e)
1649
    {
1650
      logMetacat.error("error in file lock thread from " +
1651
                                "MetacatReplication.run: " + e.getMessage());
1652
    }
1653
  }
1654

    
1655
  /**
1656
   * Returns the name of a server given a serverCode
1657
   * @param serverCode the serverid of the server
1658
   * @return the servername or null if the specified serverCode does not
1659
   *         exist.
1660
   */
1661
  public static String getServerNameForServerCode(int serverCode)
1662
  {
1663
    //System.out.println("serverid: " + serverCode);
1664
    DBConnection dbConn = null;
1665
    int serialNumber = -1;
1666
    PreparedStatement pstmt = null;
1667
    try
1668
    {
1669
      dbConn=DBConnectionPool.
1670
                  getDBConnection("MetacatReplication.getServer");
1671
      serialNumber=dbConn.getCheckOutSerialNumber();
1672
      String sql = new String("select server from " +
1673
                              "xml_replication where serverid = " +
1674
                              serverCode);
1675
      pstmt = dbConn.prepareStatement(sql);
1676
      //System.out.println("getserver sql: " + sql);
1677
      pstmt.execute();
1678
      ResultSet rs = pstmt.getResultSet();
1679
      boolean tablehasrows = rs.next();
1680
      if(tablehasrows)
1681
      {
1682
        //System.out.println("server: " + rs.getString(1));
1683
        return rs.getString(1);
1684
      }
1685

    
1686
      //conn.close();
1687
    }
1688
    catch(Exception e)
1689
    {
1690
      System.out.println("Error in MetacatReplication.getServer: " +
1691
                          e.getMessage());
1692
    }
1693
    finally
1694
    {
1695
      try
1696
      {
1697
        pstmt.close();
1698
      }//try
1699
      catch (SQLException ee)
1700
      {
1701
        logMetacat.error("Error in MetacactReplication.getserver: "+
1702
                                    ee.getMessage());
1703
      }//catch
1704
      finally
1705
      {
1706
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1707
      }//fianlly
1708
    }//finally
1709

    
1710

    
1711

    
1712
    return null;
1713
      //return null if the server does not exist
1714
  }
1715

    
1716
  /**
1717
   * Returns a server code given a server name
1718
   * @param server the name of the server
1719
   * @return integer > 0 representing the code of the server, 0 if the server
1720
   *  does not exist.
1721
   */
1722
  public static int getServerCodeForServerName(String server) throws Exception
1723
  {
1724
    DBConnection dbConn = null;
1725
    int serialNumber = -1;
1726
    PreparedStatement pstmt = null;
1727
    int serverCode = 0;
1728

    
1729
    try {
1730

    
1731
      //conn = util.openDBConnection();
1732
      dbConn=DBConnectionPool.
1733
                  getDBConnection("MetacatReplication.getServerCode");
1734
      serialNumber=dbConn.getCheckOutSerialNumber();
1735
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1736
                                    "WHERE server LIKE '" + server + "'");
1737
      pstmt.execute();
1738
      ResultSet rs = pstmt.getResultSet();
1739
      boolean tablehasrows = rs.next();
1740
      if ( tablehasrows ) {
1741
        serverCode = rs.getInt(1);
1742
        pstmt.close();
1743
        //conn.close();
1744
        return serverCode;
1745
      }
1746

    
1747
    } catch(Exception e) {
1748
      throw e;
1749

    
1750
    } finally {
1751
      try
1752
      {
1753
        pstmt.close();
1754
        //conn.close();
1755
       }//try
1756
       catch(Exception ee)
1757
       {
1758
         logMetacat.error("Error in MetacatReplicatio.getServerCode: "
1759
                                  +ee.getMessage());
1760

    
1761
       }//catch
1762
       finally
1763
       {
1764
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1765
       }//finally
1766
    }//finally
1767

    
1768
    return serverCode;
1769
  }
1770

    
1771
  /**
1772
   * Method to get a host server information for given docid
1773
   * @param conn a connection to the database
1774
   */
1775
  public static Hashtable<String,String> getHomeServerInfoForDocId(String docId)
1776
  {
1777
    Hashtable<String,String> sl = new Hashtable<String,String>();
1778
    DBConnection dbConn = null;
1779
    int serialNumber = -1;
1780
    docId=MetaCatUtil.getDocIdFromString(docId);
1781
    PreparedStatement pstmt=null;
1782
    int serverLocation;
1783
    try
1784
    {
1785
      //get conection
1786
      dbConn=DBConnectionPool.
1787
                  getDBConnection("ReplicationHandler.getHomeServer");
1788
      serialNumber=dbConn.getCheckOutSerialNumber();
1789
      //get a server location from xml_document table
1790
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
1791
                                            +"where docid = ?");
1792
      pstmt.setString(1, docId);
1793
      pstmt.execute();
1794
      ResultSet serverName = pstmt.getResultSet();
1795
      //get a server location
1796
      if(serverName.next())
1797
      {
1798
        serverLocation=serverName.getInt(1);
1799
        pstmt.close();
1800
      }
1801
      else
1802
      {
1803
        pstmt.close();
1804
        //ut.returnConnection(conn);
1805
        return null;
1806
      }
1807
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
1808
                        "from xml_replication where serverid = ?");
1809
      //increase usage count
1810
      dbConn.increaseUsageCount(1);
1811
      pstmt.setInt(1, serverLocation);
1812
      pstmt.execute();
1813
      ResultSet rs = pstmt.getResultSet();
1814
      boolean tableHasRows = rs.next();
1815
      if (tableHasRows)
1816
      {
1817

    
1818
          String server = rs.getString(1);
1819
          String last_checked = rs.getString(2);
1820
          if(!server.equals("localhost"))
1821
          {
1822
            sl.put(server, last_checked);
1823
          }
1824

    
1825
      }
1826
      else
1827
      {
1828
        pstmt.close();
1829
        //ut.returnConnection(conn);
1830
        return null;
1831
      }
1832
      pstmt.close();
1833
    }
1834
    catch(Exception e)
1835
    {
1836
      System.out.println("error in replicationHandler.getHomeServer(): " +
1837
                         e.getMessage());
1838
    }
1839
    finally
1840
    {
1841
      try
1842
      {
1843
        pstmt.close();
1844
        //ut.returnConnection(conn);
1845
      }
1846
      catch (Exception ee)
1847
      {
1848
        logMetacat.error("Eror irn rplicationHandler.getHomeServer() "+
1849
                          "to close pstmt: "+ee.getMessage());
1850
      }
1851
      finally
1852
      {
1853
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1854
      }
1855

    
1856
    }//finally
1857
    return sl;
1858
  }
1859

    
1860
  /**
1861
   * Returns a home server location  given a accnum
1862
   * @param accNum , given accNum for a document
1863
   *
1864
   */
1865
  public static int getHomeServerCodeForDocId(String accNum) throws Exception
1866
  {
1867
    DBConnection dbConn = null;
1868
    int serialNumber = -1;
1869
    PreparedStatement pstmt = null;
1870
    int serverCode = 1;
1871
    String docId=MetaCatUtil.getDocIdFromString(accNum);
1872

    
1873
    try
1874
    {
1875

    
1876
      // Get DBConnection
1877
      dbConn=DBConnectionPool.
1878
                  getDBConnection("ReplicationHandler.getServerLocation");
1879
      serialNumber=dbConn.getCheckOutSerialNumber();
1880
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1881
                              + "WHERE docid LIKE '" + docId + "'");
1882
      pstmt.execute();
1883
      ResultSet rs = pstmt.getResultSet();
1884
      boolean tablehasrows = rs.next();
1885
      //If a document is find, return the server location for it
1886
      if ( tablehasrows )
1887
      {
1888
        serverCode = rs.getInt(1);
1889
        pstmt.close();
1890
        //conn.close();
1891
        return serverCode;
1892
      }
1893
      //if couldn't find in xml_documents table, we think server code is 1
1894
      //(this is new document)
1895
      else
1896
      {
1897
        pstmt.close();
1898
        //conn.close();
1899
        return serverCode;
1900
      }
1901

    
1902
    }
1903
    catch(Exception e)
1904
    {
1905

    
1906
      throw e;
1907

    
1908
    }
1909
    finally
1910
    {
1911
      try
1912
      {
1913
        pstmt.close();
1914
        //conn.close();
1915

    
1916
      }
1917
      catch(Exception ee)
1918
      {
1919
        logMetacat.error("Erorr in Replication.getServerLocation "+
1920
                     "to close pstmt"+ee.getMessage());
1921
      }
1922
      finally
1923
      {
1924
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1925
      }//finally
1926
    }//finally
1927
   //return serverCode;
1928
  }
1929

    
1930

    
1931

    
1932
  /**
1933
   * This method returns the content of a url
1934
   * @param u the url to return the content from
1935
   * @return a string representing the content of the url
1936
   * @throws java.io.IOException
1937
   */
1938
  public static String getURLContent(URL u) throws java.io.IOException
1939
  {
1940
    char istreamChar;
1941
    int istreamInt;
1942
    logMetacat.info("Before open the stream"+u.toString());
1943
    InputStream input = u.openStream();
1944
    logMetacat.info("Afetr open the stream"+u.toString());
1945
    InputStreamReader istream = new InputStreamReader(input);
1946
    StringBuffer serverResponse = new StringBuffer();
1947
    while((istreamInt = istream.read()) != -1)
1948
    {
1949
      istreamChar = (char)istreamInt;
1950
      serverResponse.append(istreamChar);
1951
    }
1952
    istream.close();
1953
    input.close();
1954

    
1955
    return serverResponse.toString();
1956
  }
1957

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

    
1982
  /**
1983
	 * Method for writing replication messages to a log file specified in
1984
	 * metacat.properties
1985
	 */
1986
  public static void replErrorLog(String message)
1987
  {
1988
    try
1989
    {
1990
    	FileOutputStream fos = 
1991
			new FileOutputStream(PropertyService.getProperty("replication.logdir")
1992
				+ "/metacatreplicationerror.log", true);
1993
      PrintWriter pw = new PrintWriter(fos);
1994
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1995
      java.util.Date localtime = new java.util.Date();
1996
      String dateString = formatter.format(localtime);
1997
      dateString += " :: " + message;
1998
      //time stamp each entry
1999
      pw.println(dateString);
2000
      pw.flush();
2001
    }
2002
    catch(Exception e)
2003
    {
2004
      System.out.println("error writing to replication error log from " +
2005
                         "MetacatReplication.replErrorLog: " + e.getMessage());
2006
      //e.printStackTrace(System.out);
2007
    }
2008
  }
2009

    
2010
  /**
2011
   * Returns true if the replicate field for server in xml_replication is 1.
2012
   * Returns false otherwise
2013
   */
2014
  public static boolean replToServer(String server)
2015
  {
2016
    DBConnection dbConn = null;
2017
    int serialNumber = -1;
2018
    PreparedStatement pstmt = null;
2019
    try
2020
    {
2021
      dbConn=DBConnectionPool.
2022
                  getDBConnection("MetacatReplication.repltoServer");
2023
      serialNumber=dbConn.getCheckOutSerialNumber();
2024
      pstmt = dbConn.prepareStatement("select replicate from " +
2025
                                    "xml_replication where server like '" +
2026
                                     server + "'");
2027
      pstmt.execute();
2028
      ResultSet rs = pstmt.getResultSet();
2029
      boolean tablehasrows = rs.next();
2030
      if(tablehasrows)
2031
      {
2032
        int i = rs.getInt(1);
2033
        if(i == 1)
2034
        {
2035
          pstmt.close();
2036
          //conn.close();
2037
          return true;
2038
        }
2039
        else
2040
        {
2041
          pstmt.close();
2042
          //conn.close();
2043
          return false;
2044
        }
2045
      }
2046
    }
2047
    catch(Exception e)
2048
    {
2049
      System.out.println("error in MetacatReplication.replToServer: " +
2050
                         e.getMessage());
2051
    }
2052
    finally
2053
    {
2054
      try
2055
      {
2056
        pstmt.close();
2057
        //conn.close();
2058
      }//try
2059
      catch(Exception ee)
2060
      {
2061
        logMetacat.error("Error in MetacatReplication.replToServer: "
2062
                                  +ee.getMessage());
2063
      }//catch
2064
      finally
2065
      {
2066
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2067
      }//finally
2068
    }//finally
2069
    return false;
2070
    //the default if this server does not exist is to not replicate to it.
2071
  }
2072

    
2073

    
2074
}
(47-47/68)