Project

General

Profile

1 522 berkley
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements replication for metacat
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Chad Berkley
7
 *
8
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11 669 jones
 *
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 522 berkley
 */
26
27
package edu.ucsb.nceas.metacat;
28
29 1751 tao
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
30 522 berkley
import java.util.*;
31 2572 tao
import java.util.Date;
32 522 berkley
import java.io.*;
33
import java.sql.*;
34
import java.net.*;
35
import java.lang.*;
36
import java.text.*;
37
import javax.servlet.*;
38
import javax.servlet.http.*;
39 574 berkley
40 2663 sgarg
import org.apache.log4j.Logger;
41 522 berkley
import org.xml.sax.*;
42
43 561 berkley
public class MetacatReplication extends HttpServlet implements Runnable
44 2286 tao
{
45 2572 tao
  private long timeInterval;
46
  private Date firstTime;
47
  private boolean timedReplicationIsOn = false;
48 522 berkley
  Timer replicationDaemon;
49 561 berkley
  private static MetaCatUtil util = new MetaCatUtil();
50
  private Vector fileLocks = new Vector();
51
  private Thread lockThread = null;
52 1751 tao
  private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
53 2298 tao
  public static final String FORCEREPLICATEDELETE = "forcereplicatedelete";
54 2572 tao
  private static final String TIMEREPLICATION = "timedreplication";
55
  private static final String TIMEREPLICATIONINTERVAl = "timedreplicationinterval";
56
  private static final String FIRSTTIME  = "firsttimedreplication";
57
  private static final int    TIMEINTERVALLIMIT = 7200000;
58 2663 sgarg
  private static Logger logMetacat = Logger.getLogger(MetacatReplication.class);
59 3233 tao
  public static final String REPLICATIONUSER = "replication";
60 2663 sgarg
61 522 berkley
  /**
62
   * Initialize the servlet by creating appropriate database connections
63
   */
64 2286 tao
  public void init(ServletConfig config) throws ServletException
65 522 berkley
  {
66 1599 tao
     //initialize db connections to handle any update requests
67 522 berkley
    MetaCatUtil util = new MetaCatUtil();
68 2572 tao
    //deltaT = util.getOption("deltaT");
69 583 berkley
    //the default deltaT can be set from metacat.properties
70
    //create a thread to do the delta-T check but don't execute it yet
71 522 berkley
    replicationDaemon = new Timer(true);
72 2572 tao
    try
73
    {
74
       timedReplicationIsOn = (new Boolean(util.getOption(TIMEREPLICATION ).trim())).booleanValue();
75 2663 sgarg
       logMetacat.info("The timed replication on is"+timedReplicationIsOn);
76 2572 tao
       timeInterval = (new Long(util.getOption(TIMEREPLICATIONINTERVAl).trim())).longValue();
77 2663 sgarg
       logMetacat.warn("The timed replication time Inerval is "+ timeInterval);
78 2572 tao
       String firstTimeStr = util.getOption(FIRSTTIME);
79 2663 sgarg
       logMetacat.warn("first replication time form property is "+firstTimeStr);
80 2572 tao
       firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
81 2663 sgarg
       logMetacat.warn("After combine current time, the real first time is "
82
                                +firstTime.toString()+" minisec");
83 2572 tao
       // set up time replication if it is on
84
       if (timedReplicationIsOn)
85 1599 tao
       {
86 2572 tao
           replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime, timeInterval);
87
           MetacatReplication.replLog("deltaT handler started with rate=" +
88
                   timeInterval + " mini seconds at " +firstTime.toString());
89
       }
90
    }
91
    catch (Exception e)
92
    {
93
        // the timed replication in Metacat.properties file has problem
94
        // so timed replication is setting to false;
95 2663 sgarg
        logMetacat.error("Couldn't set up timed replication "+
96 2572 tao
                     " in Metacat replication servlet init because " +
97 2663 sgarg
                 e.getMessage());
98 2572 tao
        MetacatReplication.replErrorLog("Couldn't set up timed replication "+
99
                " in Metacat replication servlet init because " +
100
                e.getMessage());
101
        timedReplicationIsOn = false;
102
    }
103
104 522 berkley
  }
105 2286 tao
106
  public void destroy()
107 522 berkley
  {
108
    replicationDaemon.cancel();
109 2572 tao
110 522 berkley
  }
111 2286 tao
112 522 berkley
  public void doGet (HttpServletRequest request, HttpServletResponse response)
113 2286 tao
                     throws ServletException, IOException
114 522 berkley
  {
115
    // Process the data and send back the response
116
    handleGetOrPost(request, response);
117
  }
118
119
  public void doPost(HttpServletRequest request, HttpServletResponse response)
120 2286 tao
                     throws ServletException, IOException
121 522 berkley
  {
122
    // Process the data and send back the response
123
    handleGetOrPost(request, response);
124
  }
125 2286 tao
126
  private void handleGetOrPost(HttpServletRequest request,
127
                               HttpServletResponse response)
128
                               throws ServletException, IOException
129 522 berkley
  {
130 1020 tao
    //PrintWriter out = response.getWriter();
131
    //ServletOutputStream outPut = response.getOutputStream();
132 522 berkley
    Hashtable params = new Hashtable();
133 1020 tao
    Enumeration paramlist = request.getParameterNames();
134 2286 tao
135
136
137 837 bojilova
// NOT NEEDED - doesn't provide enough security because of possible IP spoofing
138
// REPLACED with running replication comminications over HTTPS
139
//    String requestingServerIP = request.getRemoteAddr();
140
//    InetAddress iaddr = InetAddress.getByName(requestingServerIP);
141
//    String requestingServer = iaddr.getHostName();
142 2286 tao
143 837 bojilova
    while (paramlist.hasMoreElements()) {
144 522 berkley
      String name = (String)paramlist.nextElement();
145
      String[] value = request.getParameterValues(name);
146 2286 tao
      params.put(name, value);
147 522 berkley
    }
148 2286 tao
149 840 bojilova
    String action = ((String[])params.get("action"))[0];
150
    String server = null;
151 2286 tao
152 837 bojilova
    try {
153
      // check if the server is included in the list of replicated servers
154 2286 tao
      if ( !action.equals("servercontrol") &&
155 840 bojilova
           !action.equals("stop") &&
156
           !action.equals("start") &&
157
           !action.equals("getall") ) {
158
159
        server = ((String[])params.get("server"))[0];
160 1292 tao
        if ( getServerCodeForServerName(server) == 0 ) {
161 2286 tao
          System.out.println("Action \"" + action +
162 840 bojilova
                             "\" rejected for server: " + server);
163
          return;
164
        } else {
165 2286 tao
          System.out.println("Action \"" + action +
166 840 bojilova
                             "\" accepted for server: " + server);
167
        }
168 727 berkley
      }
169 2586 tao
      else
170
      {
171
          // start, stop, getall and servercontrol need to check
172
          // if user is administor
173
          HttpSession sess = request.getSession(true);
174
          String sess_id = "";
175
          String username = "";
176
          String[] groupnames = {""};
177
          Hashtable sessionHash = MetaCatServlet.getSessionHash();
178
          if (params.containsKey("sessionid"))
179
          {
180
             sess_id = ((String[]) params.get("sessionid"))[0];
181 2663 sgarg
             logMetacat.info("in has sessionid "+ sess_id);
182 2586 tao
             if (sessionHash.containsKey(sess_id))
183
             {
184 2663 sgarg
                  logMetacat.info("find the id " + sess_id + " in hash table");
185 2586 tao
                  sess = (HttpSession) sessionHash.get(sess_id);
186
             }
187
           }
188
           username = (String) sess.getAttribute("username");
189 2663 sgarg
           logMetacat.warn("The user name from session is: "+ username);
190 2586 tao
           groupnames = (String[]) sess.getAttribute("groupnames");
191
           if (!MetaCatUtil.isAdministrator(username, groupnames))
192
           {
193
               PrintWriter out = response.getWriter();
194
               out.print("<error>");
195
               out.print("The user \"" + username +
196
                       "\" is not authorized for this action.");
197
               out.print("</error>");
198
               out.close();
199 2663 sgarg
               logMetacat.warn("The user \"" + username +
200
                       "\" is not authorized for this action: " +action);
201 2586 tao
               replErrorLog("The user \"" + username +
202
                       "\" is not authorized for this action: " +action);
203
               return;
204
           }
205
206
      }// this is final else
207 837 bojilova
    } catch (Exception e) {
208
      System.out.println("Error in MetacatReplication.handleGetOrPost: " +
209
                         e.getMessage() );
210 727 berkley
      return;
211
    }
212 2586 tao
213 2286 tao
    if ( action.equals("readdata") )
214 1020 tao
    {
215 2586 tao
      OutputStream outStream = response.getOutputStream();
216 1020 tao
      //to get the data file.
217 2586 tao
      handleGetDataFileRequest(outStream, params, response);
218
      outStream.close();
219 1020 tao
    }
220 2286 tao
    else if ( action.equals("forcereplicatedatafile") )
221 1023 tao
    {
222
      //read a specific docid from remote host, and store it into local host
223 3233 tao
      handleForceReplicateDataFileRequest(params, request);
224 2286 tao
225 1023 tao
    }
226 1020 tao
    else
227
    {
228
    PrintWriter out = response.getWriter();
229 840 bojilova
    if ( action.equals("stop") ) {
230 837 bojilova
      //stop the replication server
231
      replicationDaemon.cancel();
232
      replicationDaemon = new Timer(true);
233 2572 tao
      timedReplicationIsOn = false;
234
      MetaCatUtil.setOption(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
235 837 bojilova
      out.println("Replication Handler Stopped");
236
      MetacatReplication.replLog("deltaT handler stopped");
237
238 2286 tao
239 840 bojilova
    } else if ( action.equals("start") ) {
240 2572 tao
       String firstTimeStr = "";
241 837 bojilova
      //start the replication server
242 2572 tao
       if ( params.containsKey("rate") ) {
243
        timeInterval = new Long(
244
               new String(((String[])params.get("rate"))[0])).longValue();
245
        if(timeInterval < TIMEINTERVALLIMIT) {
246
            out.println("Replication deltaT rate cannot be less than "+
247
                    TIMEINTERVALLIMIT + " millisecs and system automatically setup the rate to "+TIMEINTERVALLIMIT);
248 583 berkley
            //deltaT<30 is a timing mess!
249 2572 tao
            timeInterval = TIMEINTERVALLIMIT;
250 549 berkley
        }
251 837 bojilova
      } else {
252 2572 tao
        timeInterval = TIMEINTERVALLIMIT ;
253 837 bojilova
      }
254 2663 sgarg
      logMetacat.info("New rate is: " + timeInterval + " mini seconds.");
255 2572 tao
      if ( params.containsKey("firsttime"))
256
      {
257
         firstTimeStr = ((String[])params.get("firsttime"))[0];
258
         try
259
         {
260
           firstTime = ReplicationHandler.combinateCurrentDateAndGivenTime(firstTimeStr);
261 2663 sgarg
           logMetacat.info("The first time setting is "+firstTime.toString());
262 2572 tao
         }
263
         catch (Exception e)
264
         {
265
            throw new ServletException(e.getMessage());
266
         }
267 2663 sgarg
         logMetacat.warn("After combine current time, the real first time is "
268
                                  +firstTime.toString()+" minisec");
269 2572 tao
      }
270
      else
271
      {
272
          MetacatReplication.replErrorLog("You should specify the first time " +
273
                                          "to start a time replication");
274 2663 sgarg
          logMetacat.warn("You should specify the first time " +
275
                                  "to start a time replication");
276 2572 tao
          return;
277
      }
278
279
      timedReplicationIsOn = true;
280
      // save settings to property file
281
      MetaCatUtil.setOption(TIMEREPLICATION, (new Boolean(timedReplicationIsOn)).toString());
282
      // note we couldn't use firstTime object because it has date info
283
      // we only need time info such as 10:00 PM
284
      MetaCatUtil.setOption(FIRSTTIME, firstTimeStr);
285
      MetaCatUtil.setOption(TIMEREPLICATIONINTERVAl, (new Long(timeInterval)).toString());
286 837 bojilova
      replicationDaemon.cancel();
287
      replicationDaemon = new Timer(true);
288 2572 tao
      replicationDaemon.scheduleAtFixedRate(new ReplicationHandler(), firstTime,
289
                                            timeInterval);
290 837 bojilova
      out.println("Replication Handler Started");
291 2286 tao
      MetacatReplication.replLog("deltaT handler started with rate=" +
292 2572 tao
                                    timeInterval + " milliseconds at " +firstTime.toString());
293 837 bojilova
294 2286 tao
295 840 bojilova
    } else if ( action.equals("getall") ) {
296 837 bojilova
      //updates this server exactly once
297 2572 tao
      replicationDaemon.schedule(new ReplicationHandler(), 0);
298 837 bojilova
      response.setContentType("text/html");
299
      out.println("<html><body>\"Get All\" Done</body></html>");
300
301 840 bojilova
    } else if ( action.equals("forcereplicate") ) {
302 1020 tao
      //read a specific docid from remote host, and store it into local host
303 3233 tao
      handleForceReplicateRequest(out, params, response, request);
304 2286 tao
305 2298 tao
    } else if ( action.equals(FORCEREPLICATEDELETE) ) {
306
      //read a specific docid from remote host, and store it into local host
307 3233 tao
      handleForceReplicateDeleteRequest(out, params, response, request);
308 2298 tao
309 840 bojilova
    } else if ( action.equals("update") ) {
310 837 bojilova
      //request an update list from the server
311
      handleUpdateRequest(out, params, response);
312
313 840 bojilova
    } else if ( action.equals("read") ) {
314 837 bojilova
      //request a specific document from the server
315
      //note that this could be replaced by a call to metacatServlet
316
      //handleGetDocumentAction().
317
      handleGetDocumentRequest(out, params, response);
318 840 bojilova
    } else if ( action.equals("getlock") ) {
319 837 bojilova
      handleGetLockRequest(out, params, response);
320
321 840 bojilova
    } else if ( action.equals("getdocumentinfo") ) {
322 837 bojilova
      handleGetDocumentInfoRequest(out, params, response);
323
324 840 bojilova
    } else if ( action.equals("gettime") ) {
325 837 bojilova
      handleGetTimeRequest(out, params, response);
326
327 840 bojilova
    } else if ( action.equals("getcatalog") ) {
328 837 bojilova
      handleGetCatalogRequest(out, params, response, true);
329
330 840 bojilova
    } else if ( action.equals("servercontrol") ) {
331 837 bojilova
      handleServerControlRequest(out, params, response);
332 1097 tao
    } else if ( action.equals("test") ) {
333
      response.setContentType("text/html");
334
      out.println("<html><body>Test successfully</body></html>");
335 837 bojilova
    }
336 2286 tao
337 840 bojilova
    out.close();
338 1020 tao
    }//else
339 522 berkley
  }
340 2286 tao
341
  /**
342 595 berkley
   * This method can add, delete and list the servers currently included in
343
   * xml_replication.
344
   * action           subaction            other needed params
345
   * ---------------------------------------------------------
346
   * servercontrol    add                  server
347
   * servercontrol    delete               server
348 2286 tao
   * servercontrol    list
349 595 berkley
   */
350
  private void handleServerControlRequest(PrintWriter out, Hashtable params,
351
                                          HttpServletResponse response)
352
  {
353
    String subaction = ((String[])params.get("subaction"))[0];
354 1217 tao
    DBConnection dbConn = null;
355
    int serialNumber = -1;
356
    PreparedStatement pstmt = null;
357 1292 tao
    String replicate =null;
358
    String server = null;
359
    String dataReplicate = null;
360
    String hub = null;
361 837 bojilova
    try {
362 1217 tao
      //conn = util.openDBConnection();
363
      dbConn=DBConnectionPool.
364
               getDBConnection("MetacatReplication.handleServerControlRequest");
365
      serialNumber=dbConn.getCheckOutSerialNumber();
366 2286 tao
367 837 bojilova
      // add server to server list
368
      if ( subaction.equals("add") ) {
369 1292 tao
        replicate = ((String[])params.get("replicate"))[0];
370
        server = ((String[])params.get("server"))[0];
371 2286 tao
372 1292 tao
        //Get data replication value
373
        dataReplicate = ((String[])params.get("datareplicate"))[0];
374
        //Get hub value
375
        hub = ((String[])params.get("hub"))[0];
376 2286 tao
377 1751 tao
        /*pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
378 1292 tao
                  "(server, last_checked, replicate, datareplicate, hub) " +
379 837 bojilova
                                      "VALUES ('" + server + "', to_date(" +
380
                                      "'01/01/00', 'MM/DD/YY'), '" +
381 1292 tao
                                      replicate +"', '" +dataReplicate+"', '"
382 1751 tao
                                      + hub +"')");*/
383
        pstmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
384
                  "(server, last_checked, replicate, datareplicate, hub) " +
385 2286 tao
                                      "VALUES ('" + server + "', "+
386
                                      dbAdapter.toDate("01/01/1980", "MM/DD/YYYY")
387 1751 tao
                                      + ", '" +
388
                                      replicate +"', '" +dataReplicate+"', '"
389 1292 tao
                                      + hub +"')");
390 2286 tao
391 595 berkley
        pstmt.execute();
392 837 bojilova
        pstmt.close();
393 1217 tao
        dbConn.commit();
394 2286 tao
        out.println("Server " + server + " added");
395 631 berkley
        response.setContentType("text/html");
396
        out.println("<html><body><table border=\"1\">");
397
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
398 1292 tao
        out.println("<b>replicate</b></td>");
399
        out.println("<td><b>datareplicate</b></td>");
400
        out.println("<td><b>hub</b></td></tr>");
401 1217 tao
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
402
        //increase dbconnection usage
403
        dbConn.increaseUsageCount(1);
404 2286 tao
405 631 berkley
        pstmt.execute();
406
        ResultSet rs = pstmt.getResultSet();
407
        boolean tablehasrows = rs.next();
408 837 bojilova
        while(tablehasrows) {
409 631 berkley
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
410
          out.println(rs.getString(3) + "</td><td>");
411 1292 tao
          out.println(rs.getString(4) + "</td><td>");
412
          out.println(rs.getString(5) + "</td><td>");
413
          out.println(rs.getString(6) + "</td></tr>");
414 2286 tao
415 631 berkley
          tablehasrows = rs.next();
416
        }
417
        out.println("</table></body></html>");
418 2286 tao
419 840 bojilova
        // download certificate with the public key on this server
420
        // and import it as a trusted certificate
421
        String certURL = ((String[])params.get("certificate"))[0];
422
        downloadCertificate(certURL);
423 2286 tao
424 837 bojilova
      // delete server from server list
425
      } else if ( subaction.equals("delete") ) {
426 1292 tao
        server = ((String[])params.get("server"))[0];
427 1217 tao
        pstmt = dbConn.prepareStatement("DELETE FROM xml_replication " +
428 837 bojilova
                                      "WHERE server LIKE '" + server + "'");
429 595 berkley
        pstmt.execute();
430 837 bojilova
        pstmt.close();
431 1217 tao
        dbConn.commit();
432 837 bojilova
        out.println("Server " + server + " deleted");
433 631 berkley
        response.setContentType("text/html");
434
        out.println("<html><body><table border=\"1\">");
435
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
436 1292 tao
        out.println("<b>replicate</b></td>");
437
        out.println("<td><b>datareplicate</b></td>");
438
        out.println("<td><b>hub</b></td></tr>");
439 2286 tao
440 1217 tao
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
441
        //increase dbconnection usage
442
        dbConn.increaseUsageCount(1);
443 631 berkley
        pstmt.execute();
444
        ResultSet rs = pstmt.getResultSet();
445
        boolean tablehasrows = rs.next();
446
        while(tablehasrows)
447
        {
448
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
449
          out.println(rs.getString(3) + "</td><td>");
450 1292 tao
          out.println(rs.getString(4) + "</td><td>");
451
          out.println(rs.getString(5) + "</td><td>");
452
          out.println(rs.getString(6) + "</td></tr>");
453 631 berkley
          tablehasrows = rs.next();
454
        }
455
        out.println("</table></body></html>");
456 837 bojilova
457
      // list servers in server list
458
      } else if ( subaction.equals("list") ) {
459 595 berkley
        response.setContentType("text/html");
460
        out.println("<html><body><table border=\"1\">");
461 629 berkley
        out.println("<tr><td><b>server</b></td><td><b>last_checked</b></td><td>");
462 1292 tao
        out.println("<b>replicate</b></td>");
463
        out.println("<td><b>datareplicate</b></td>");
464
        out.println("<td><b>hub</b></td></tr>");
465 1217 tao
        pstmt = dbConn.prepareStatement("SELECT * FROM xml_replication");
466 595 berkley
        pstmt.execute();
467
        ResultSet rs = pstmt.getResultSet();
468
        boolean tablehasrows = rs.next();
469 837 bojilova
        while(tablehasrows) {
470 595 berkley
          out.println("<tr><td>" + rs.getString(2) + "</td><td>");
471 629 berkley
          out.println(rs.getString(3) + "</td><td>");
472 1292 tao
          out.println(rs.getString(4) + "</td><td>");
473
          out.println(rs.getString(5) + "</td><td>");
474
          out.println(rs.getString(6) + "</td></tr>");
475 595 berkley
          tablehasrows = rs.next();
476
        }
477
        out.println("</table></body></html>");
478 2286 tao
      }
479 1292 tao
      else
480
      {
481 2286 tao
482 1292 tao
        out.println("<error>Unkonwn subaction</error>");
483 2286 tao
484 595 berkley
      }
485 667 berkley
      pstmt.close();
486 1217 tao
      //conn.close();
487 837 bojilova
488
    } catch(Exception e) {
489 2286 tao
      System.out.println("Error in " +
490
                         "MetacatReplication.handleServerControlRequest " +
491 595 berkley
                         e.getMessage());
492
      e.printStackTrace(System.out);
493
    }
494 1217 tao
    finally
495
    {
496
      try
497
      {
498
        pstmt.close();
499
      }//try
500
      catch (SQLException ee)
501
      {
502 2663 sgarg
        logMetacat.error("Error in " +
503 1217 tao
                "MetacatReplication.handleServerControlRequest to close pstmt "
504 2663 sgarg
                 + ee.getMessage());
505 1217 tao
      }//catch
506
      finally
507
      {
508
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
509
      }//finally
510
    }//finally
511 2286 tao
512 595 berkley
  }
513 2286 tao
514
  // download certificate with the public key from certURL and
515
  // upload it onto this server; it then must be imported as a
516
  // trusted certificate
517 840 bojilova
  private void downloadCertificate (String certURL)
518
                throws FileNotFoundException, IOException, MalformedURLException
519
  {
520
    MetaCatUtil util = new MetaCatUtil();
521
    String certPath = util.getOption("certPath"); //the path to be uploaded to
522 2286 tao
523 840 bojilova
    // get filename from the URL of the certificate
524
    String filename = certURL;
525
    int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
526
    if ( slash > -1 ) {
527
      filename = filename.substring(slash + 1);
528
    }
529 2286 tao
530 840 bojilova
    // open file output strem to write the input into it
531
    File f = new File(certPath, filename);
532 2286 tao
    synchronized (f) {
533 840 bojilova
      try {
534
        if ( f.exists() ) {
535
          throw new IOException("File already exist: " + f.getCanonicalFile());
536
          //if ( f.exists() && !f.canWrite() ) {
537
          //  throw new IOException("Not writable: " + f.getCanonicalFile());
538
        }
539
      } catch (SecurityException se) {
540
        // if a security manager exists,
541
        // its checkRead method is called for f.exist()
542
        // or checkWrite method is called for f.canWrite()
543
        throw se;
544
      }
545 2286 tao
546 840 bojilova
      // create a buffered byte output stream
547
      // that uses a default-sized output buffer
548
      FileOutputStream fos = new FileOutputStream(f);
549
      BufferedOutputStream out = new BufferedOutputStream(fos);
550
551
      // this should be http url
552
      URL url = new URL(certURL);
553
      BufferedInputStream bis = null;
554
      try {
555
        bis = new BufferedInputStream(url.openStream());
556
        byte[] buf = new byte[4 * 1024]; // 4K buffer
557
        int b = bis.read(buf);
558
        while (b != -1) {
559
          out.write(buf, 0, b);
560
          b = bis.read(buf);
561
        }
562
      } finally {
563
        if (bis != null) bis.close();
564
      }
565
      // the input and the output streams must be closed
566
      bis.close();
567 2286 tao
            out.flush();
568
            out.close();
569
            fos.close();
570 840 bojilova
    } // end of synchronized(f)
571
  }
572 2286 tao
573 583 berkley
  /**
574 1020 tao
   * when a forcereplication request comes in, local host sends a read request
575
   * to the requesting server (remote server) for the specified docid.
576
   * Then store it in local database.
577 583 berkley
   */
578 574 berkley
  private void handleForceReplicateRequest(PrintWriter out, Hashtable params,
579 3233 tao
                                           HttpServletResponse response, HttpServletRequest request)
580 574 berkley
  {
581 837 bojilova
    String server = ((String[])params.get("server"))[0]; // the server that
582
    String docid = ((String[])params.get("docid"))[0]; // sent the document
583
    String dbaction = "UPDATE"; // the default action is UPDATE
584 577 berkley
    boolean override = false;
585
    int serverCode = 1;
586 1217 tao
    DBConnection dbConn = null;
587
    int serialNumber = -1;
588 2286 tao
589 837 bojilova
    try {
590
      //if the url contains a dbaction then the default action is overridden
591
      if(params.containsKey("dbaction")) {
592 577 berkley
        dbaction = ((String[])params.get("dbaction"))[0];
593 1057 tao
        //serverCode = MetacatReplication.getServerCode(server);
594
        //override = true; //we are now overriding the default action
595 577 berkley
      }
596 1292 tao
      MetacatReplication.replLog("force replication request from " + server);
597 2663 sgarg
      logMetacat.info("Force replication request from: "+ server);
598
      logMetacat.info("Force replication docid: "+docid);
599
      logMetacat.info("Force replication action: "+dbaction);
600 1292 tao
      // sending back read request to remote server
601 1014 tao
      URL u = new URL("https://" + server + "?server="
602
                +util.getLocalReplicationServerName()
603
                +"&action=read&docid=" + docid);
604 574 berkley
      String xmldoc = MetacatReplication.getURLContent(u);
605 2286 tao
606 837 bojilova
      // get the document info from server
607 2286 tao
      URL docinfourl = new URL("https://" + server +
608 1014 tao
                               "?server="+util.getLocalReplicationServerName()
609
                               +"&action=getdocumentinfo&docid=" + docid);
610 2286 tao
611 574 berkley
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
612 2286 tao
613 837 bojilova
      //dih is the parser for the docinfo xml format
614 574 berkley
      DocInfoHandler dih = new DocInfoHandler();
615
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
616
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
617
      Hashtable docinfoHash = dih.getDocInfo();
618 2286 tao
619 1292 tao
      // Get user owner of this docid
620 574 berkley
      String user = (String)docinfoHash.get("user_owner");
621 1292 tao
      // Get home server of this docid
622 1057 tao
      String homeServer=(String)docinfoHash.get("home_server");
623 2624 tao
      String createdDate = (String)docinfoHash.get("date_created");
624
      String updatedDate = (String)docinfoHash.get("date_updated");
625 2663 sgarg
      logMetacat.info("homeServer: "+homeServer);
626 1561 tao
      // Get Document type
627
      String docType = (String)docinfoHash.get("doctype");
628 2663 sgarg
      logMetacat.info("docType: "+docType);
629 1561 tao
      String parserBase = null;
630
      // this for eml2 and we need user eml2 parser
631 2286 tao
      if (docType != null &&
632 2169 sgarg
          (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
633 1561 tao
      {
634 2663 sgarg
         logMetacat.warn("This is an eml200 document!");
635 2163 tao
         parserBase = DocumentImpl.EML200;
636 1561 tao
      }
637 2286 tao
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_1NAMESPACE))
638
      {
639 2663 sgarg
         logMetacat.warn("This is an eml2.0.1 document!");
640 2286 tao
         parserBase = DocumentImpl.EML200;
641
      }
642
      else if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_1_0NAMESPACE))
643
      {
644 2663 sgarg
         logMetacat.warn("This is an eml2.1.0 document!");
645 2286 tao
         parserBase = DocumentImpl.EML210;
646
      }
647 2663 sgarg
      logMetacat.warn("The parserBase is: "+parserBase);
648 2286 tao
649 1292 tao
      // Get DBConnection from pool
650 1217 tao
      dbConn=DBConnectionPool.
651
              getDBConnection("MetacatReplication.handleForceReplicateRequest");
652
      serialNumber=dbConn.getCheckOutSerialNumber();
653 1292 tao
      // write the document to local database
654 1561 tao
      DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false);
655 2286 tao
      wrapper.writeReplication(dbConn, new StringReader(xmldoc), null, null,
656 2624 tao
                               dbaction, docid, user, null, homeServer,
657 3230 tao
                               server, createdDate, updatedDate);
658
659 584 berkley
      MetacatReplication.replLog("document " + docid + " added to DB with " +
660
                                 "action " + dbaction);
661 3233 tao
      EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
662 1292 tao
    }//try
663 2286 tao
    catch(Exception e)
664 1292 tao
    {
665 2286 tao
      MetacatReplication.replErrorLog("document " + docid +
666 1583 tao
                                      " failed to added to DB with " +
667
                                      "action " + dbaction + " because "+
668
                                       e.getMessage());
669 2663 sgarg
      logMetacat.error("ERROR in MetacatReplication.handleForceReplicate" +
670
                         "Request(): " + e.getMessage());
671 2286 tao
672 1292 tao
    }//catch
673 1217 tao
    finally
674
    {
675 1292 tao
      // Return the checked out DBConnection
676 1217 tao
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
677
    }//finally
678 574 berkley
  }
679 2286 tao
680 2298 tao
/*
681
 * when a forcereplication delete request comes in, local host will delete this
682
 * document
683
 */
684
private void handleForceReplicateDeleteRequest(PrintWriter out, Hashtable params,
685 3233 tao
                                         HttpServletResponse response, HttpServletRequest request)
686 2298 tao
{
687
  String server = ((String[])params.get("server"))[0]; // the server that
688
  String docid = ((String[])params.get("docid"))[0]; // sent the document
689
  try
690
  {
691
    MetacatReplication.replLog("force replication delete request from " + server);
692
    MetacatReplication.replLog("force replication delete docid " + docid);
693 2663 sgarg
    logMetacat.info("Force replication delete request from: "+ server);
694
    logMetacat.info("Force replication delete docid: "+docid);
695 3230 tao
    DocumentImpl.delete(docid, null, null, server);
696 2298 tao
    MetacatReplication.replLog("document " + docid + " was successfully deleted ");
697 3233 tao
    EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, "delete");
698 2663 sgarg
    logMetacat.info("document " + docid + " was successfully deleted ");
699 2298 tao
  }
700
  catch(Exception e)
701
  {
702
    MetacatReplication.replErrorLog("document " + docid +
703
                                    " failed to delete because "+
704
                                     e.getMessage());
705 2663 sgarg
    logMetacat.error("ERROR in MetacatReplication.handleForceDeleteReplicate" +
706
                       "Request(): " + e.getMessage());
707 2298 tao
708
  }//catch
709
710
}
711
712
713 561 berkley
  /**
714 2286 tao
   * when a forcereplication data file request comes in, local host sends a
715
   * readdata request to the requesting server (remote server) for the specified
716 1023 tao
   * docid. Then store it in local database and file system
717
   */
718 3233 tao
  private void handleForceReplicateDataFileRequest(Hashtable params, HttpServletRequest request)
719 1023 tao
  {
720 2286 tao
721 1023 tao
    //make sure there is some parameters
722
    if(params.isEmpty())
723
    {
724
      return;
725
    }
726 2286 tao
    // Get remote server
727
    String server = ((String[])params.get("server"))[0];
728 1292 tao
    // the docid should include rev number
729 2286 tao
    String docid = ((String[])params.get("docid"))[0];
730 1292 tao
    // Make sure there is a docid and server
731
    if (docid==null || server==null || server.equals(""))
732 1023 tao
    {
733 2663 sgarg
      logMetacat.error("Didn't specify docid or server for replication");
734 1023 tao
      return;
735
    }
736 2286 tao
737 1292 tao
    // Overide or not
738 1023 tao
    boolean override = false;
739 1292 tao
    // dbaction - update or insert
740 1023 tao
    String dbaction=null;
741 2286 tao
742
    try
743 1023 tao
    {
744 1292 tao
      //docid was switch to two parts uinque code and rev
745 2650 tao
      //String uniqueCode=MetaCatUtil.getDocIdFromString(docid);
746
      //int rev=MetaCatUtil.getVersionFromString(docid);
747 2286 tao
      if(params.containsKey("dbaction"))
748 1023 tao
      {
749
        dbaction = ((String[])params.get("dbaction"))[0];
750
      }
751
      else//default value is update
752
      {
753
        dbaction = "update";
754
      }
755 2286 tao
756
      MetacatReplication.replLog("force replication request from " + server);
757 2663 sgarg
      logMetacat.info("Force replication request from: "+ server);
758
      logMetacat.info("Force replication docid: "+docid);
759
      logMetacat.info("Force replication action: "+dbaction);
760 1023 tao
      // get the document info from server
761 2286 tao
      URL docinfourl = new URL("https://" + server +
762 1023 tao
                               "?server="+util.getLocalReplicationServerName()
763 2650 tao
                               +"&action=getdocumentinfo&docid=" + docid);
764 2286 tao
765 1023 tao
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
766
767
      //dih is the parser for the docinfo xml format
768
      DocInfoHandler dih = new DocInfoHandler();
769
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
770
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
771
      Hashtable docinfoHash = dih.getDocInfo();
772
      String user = (String)docinfoHash.get("user_owner");
773 2286 tao
774 1023 tao
      String docName = (String)docinfoHash.get("docname");
775 2286 tao
776 1023 tao
      String docType = (String)docinfoHash.get("doctype");
777 2286 tao
778 1065 tao
      String docHomeServer= (String)docinfoHash.get("home_server");
779 2624 tao
780
      String createdDate = (String)docinfoHash.get("date_created");
781
782
      String updatedDate = (String)docinfoHash.get("date_updated");
783 2663 sgarg
      logMetacat.info("docHomeServer of datafile: "+docHomeServer);
784 2286 tao
785
786
787 1023 tao
      //if action is delete, we don't delete the data file. Just archieve
788
      //the xml_documents
789 2298 tao
      /*if (dbaction.equals("delete"))
790 1023 tao
      {
791 1217 tao
        //conn = util.getConnection();
792
        DocumentImpl.delete(docid,user,null);
793
        //util.returnConnection(conn);
794 2298 tao
      }*/
795 1031 tao
      //To data file insert or update is same
796 2298 tao
      if (dbaction.equals("insert")||dbaction.equals("update"))
797 1023 tao
      {
798
        //Get data file and store it into local file system.
799
        // sending back readdata request to server
800
        URL url = new URL("https://" + server + "?server="
801
                +util.getLocalReplicationServerName()
802
                +"&action=readdata&docid=" + docid);
803 1031 tao
        String datafilePath = util.getOption("datafilepath");
804
        //register data file into xml_documents table and wite data file
805
        //into file system
806 2286 tao
        DocumentImpl.writeDataFileInReplication(url.openStream(), datafilePath,
807 2608 tao
                            docName, docType, docid, user,docHomeServer,server,
808 3230 tao
                            DocumentImpl.DOCUMENTTABLE, false, createdDate, updatedDate);
809 2624 tao
                            //false means non-timed replication
810 3233 tao
        MetacatReplication.replLog("datafile " + docid + " added to DB with " +
811
                "action " + dbaction);
812
        EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
813 1023 tao
     }
814 2286 tao
815
816
817 3233 tao
818 2286 tao
    }
819
    catch(Exception e)
820 1023 tao
    {
821 2286 tao
822
      MetacatReplication.replErrorLog("Datafile " + docid +
823 1583 tao
                                      " failed to added to DB with " +
824
                                      "action " + dbaction + " because "+
825
                                       e.getMessage());
826 2663 sgarg
      logMetacat.error
827 1292 tao
              ("ERROR in MetacatReplication.handleForceDataFileReplicate" +
828 2663 sgarg
                         "Request(): " + e.getMessage());
829 1023 tao
    }
830
  }
831
  /**
832 561 berkley
   * Grants or denies a lock to a requesting host.
833
   * The servlet parameters of interrest are:
834
   * docid: the docid of the file the lock is being requested for
835
   * currentdate: the timestamp of the document on the remote server
836 2286 tao
   *
837 561 berkley
   */
838
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
839
                                    HttpServletResponse response)
840
  {
841 1292 tao
842 561 berkley
    try
843
    {
844 2286 tao
845 561 berkley
      String docid = ((String[])params.get("docid"))[0];
846 580 berkley
      String remoteRev = ((String[])params.get("updaterev"))[0];
847 1217 tao
      DocumentImpl requestDoc = new DocumentImpl(docid);
848 584 berkley
      MetacatReplication.replLog("lock request for " + docid);
849 580 berkley
      int localRevInt = requestDoc.getRev();
850
      int remoteRevInt = Integer.parseInt(remoteRev);
851 2286 tao
852 580 berkley
      if(remoteRevInt >= localRevInt)
853 561 berkley
      {
854
        if(!fileLocks.contains(docid))
855 580 berkley
        { //grant the lock if it is not already locked
856 561 berkley
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
857
          //send a message back to the the remote host authorizing the insert
858
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
859
          lockThread = new Thread(this);
860
          lockThread.setPriority(Thread.MIN_PRIORITY);
861
          lockThread.start();
862 584 berkley
          MetacatReplication.replLog("lock granted for " + docid);
863 561 berkley
        }
864
        else
865
        { //deny the lock
866
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
867 2286 tao
          MetacatReplication.replLog("lock denied for " + docid +
868 584 berkley
                                     "reason: file already locked");
869 561 berkley
        }
870
      }
871
      else
872
      {//deny the lock.
873
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
874 2286 tao
        MetacatReplication.replLog("lock denied for " + docid +
875 584 berkley
                                   "reason: client has outdated file");
876 561 berkley
      }
877 1217 tao
      //conn.close();
878 561 berkley
    }
879
    catch(Exception e)
880
    {
881 675 berkley
      System.out.println("error requesting file lock from MetacatReplication." +
882
                         "handleGetLockRequest: " + e.getMessage());
883 568 berkley
      e.printStackTrace(System.out);
884 561 berkley
    }
885
  }
886 2286 tao
887 561 berkley
  /**
888
   * Sends all of the xml_documents information encoded in xml to a requestor
889 583 berkley
   * the format is:
890
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
891 1057 tao
   *                  user_updated, home_server, public_access, rev)/>
892 583 berkley
   * all of the subelements of document info are #PCDATA
893 561 berkley
   */
894 2286 tao
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params,
895 561 berkley
                                        HttpServletResponse response)
896
  {
897
    String docid = ((String[])(params.get("docid")))[0];
898
    StringBuffer sb = new StringBuffer();
899 2286 tao
900 561 berkley
    try
901
    {
902 2286 tao
903 1217 tao
      DocumentImpl doc = new DocumentImpl(docid);
904 561 berkley
      sb.append("<documentinfo><docid>").append(docid);
905
      sb.append("</docid><docname>").append(doc.getDocname());
906
      sb.append("</docname><doctype>").append(doc.getDoctype());
907 692 bojilova
      sb.append("</doctype>");
908
      sb.append("<user_owner>").append(doc.getUserowner());
909 561 berkley
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
910 1057 tao
      sb.append("</user_updated>");
911 2624 tao
      sb.append("<date_created>");
912
      sb.append(doc.getCreateDate());
913
      sb.append("</date_created>");
914
      sb.append("<date_updated>");
915
      sb.append(doc.getUpdateDate());
916
      sb.append("</date_updated>");
917 1057 tao
      sb.append("<home_server>");
918 1061 tao
      sb.append(doc.getDocHomeServer());
919 1057 tao
      sb.append("</home_server>");
920
      sb.append("<public_access>").append(doc.getPublicaccess());
921 583 berkley
      sb.append("</public_access><rev>").append(doc.getRev());
922
      sb.append("</rev></documentinfo>");
923 561 berkley
      response.setContentType("text/xml");
924
      out.println(sb.toString());
925 2286 tao
926 561 berkley
    }
927
    catch (Exception e)
928
    {
929 675 berkley
      System.out.println("error in " +
930 2286 tao
                         "metacatReplication.handlegetdocumentinforequest: " +
931 675 berkley
                          e.getMessage());
932 561 berkley
    }
933 2286 tao
934 561 berkley
  }
935 2286 tao
936 1020 tao
  /**
937
   * Sends a datafile to a remote host
938
   */
939 2286 tao
  private void handleGetDataFileRequest(OutputStream outPut,
940 1020 tao
                            Hashtable params, HttpServletResponse response)
941 2286 tao
942 1020 tao
  {
943 2286 tao
    // File path for data file
944 1020 tao
    String filepath = util.getOption("datafilepath");
945 1292 tao
    // Request docid
946 1020 tao
    String docId = ((String[])(params.get("docid")))[0];
947 1023 tao
    //check if the doicd is null
948
    if (docId==null)
949
    {
950 2663 sgarg
      logMetacat.error("Didn't specify docid for replication");
951 1023 tao
      return;
952
    }
953 2286 tao
954 1097 tao
    //try to open a https stream to test if the request server's public key
955
    //in the key store, this is security issue
956
    try
957
    {
958
      String server = ((String[])params.get("server"))[0];
959
      URL u = new URL("https://" + server + "?server="
960
                +util.getLocalReplicationServerName()
961
                +"&action=test");
962
      String test = MetacatReplication.getURLContent(u);
963
      //couldn't pass the test
964
      if (test.indexOf("successfully")==-1)
965
      {
966
        //response.setContentType("text/xml");
967
        //outPut.println("<error>Couldn't pass the trust test</error>");
968 2663 sgarg
        logMetacat.error("Couldn't pass the trust test");
969 1097 tao
        return;
970
      }
971
    }//try
972
    catch (Exception ee)
973
    {
974
      return;
975
    }//catch
976 2286 tao
977
    if(!filepath.endsWith("/"))
978 1020 tao
    {
979
          filepath += "/";
980
    }
981 1292 tao
    // Get file aboslute file name
982 2286 tao
    String filename = filepath + docId;
983
984 1292 tao
    //MIME type
985
    String contentType = null;
986 2286 tao
    if (filename.endsWith(".xml"))
987 1292 tao
    {
988
        contentType="text/xml";
989 2286 tao
    }
990
    else if (filename.endsWith(".css"))
991 1292 tao
    {
992
        contentType="text/css";
993 2286 tao
    }
994
    else if (filename.endsWith(".dtd"))
995 1292 tao
    {
996
        contentType="text/plain";
997 2286 tao
    }
998
    else if (filename.endsWith(".xsd"))
999 1292 tao
    {
1000
        contentType="text/xml";
1001 2286 tao
    }
1002
    else if (filename.endsWith("/"))
1003 1292 tao
    {
1004
        contentType="text/html";
1005 2286 tao
    }
1006
    else
1007 1292 tao
    {
1008
        File f = new File(filename);
1009 2286 tao
        if ( f.isDirectory() )
1010 1292 tao
        {
1011
           contentType="text/html";
1012 2286 tao
        }
1013 1292 tao
        else
1014
        {
1015
           contentType="application/octet-stream";
1016
        }
1017
     }
1018 2286 tao
1019 1292 tao
   // Set the mime type
1020 1020 tao
   response.setContentType(contentType);
1021 2286 tao
1022 1292 tao
   // Get the content of the file
1023 1020 tao
   FileInputStream fin = null;
1024 2286 tao
   try
1025 1020 tao
   {
1026 1292 tao
      // FileInputStream to metacat
1027 1020 tao
      fin = new FileInputStream(filename);
1028 1292 tao
      // 4K buffer
1029
      byte[] buf = new byte[4 * 1024];
1030
      // Read data from file input stream to byte array
1031 1020 tao
      int b = fin.read(buf);
1032 1292 tao
      // Write to outStream from byte array
1033 2286 tao
      while (b != -1)
1034 1020 tao
      {
1035
        outPut.write(buf, 0, b);
1036
        b = fin.read(buf);
1037
      }
1038 1292 tao
      // close file input stream
1039 1020 tao
      fin.close();
1040 2286 tao
1041 1292 tao
   }//try
1042 1020 tao
   catch(Exception e)
1043
   {
1044
      System.out.println("error getting data file from MetacatReplication." +
1045
                         "handlGetDataFileRequest " + e.getMessage());
1046
      e.printStackTrace(System.out);
1047 1292 tao
   }//catch
1048 2286 tao
1049 1020 tao
}
1050 2286 tao
1051
1052 561 berkley
  /**
1053
   * Sends a document to a remote host
1054
   */
1055 2286 tao
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params,
1056 561 berkley
                                        HttpServletResponse response)
1057 534 berkley
  {
1058 2286 tao
1059 534 berkley
    try
1060
    {
1061 1097 tao
      //try to open a https stream to test if the request server's public key
1062
      //in the key store, this is security issue
1063
      String server = ((String[])params.get("server"))[0];
1064
      URL u = new URL("https://" + server + "?server="
1065
                +util.getLocalReplicationServerName()
1066
                +"&action=test");
1067
      String test = MetacatReplication.getURLContent(u);
1068
      //couldn't pass the test
1069
      if (test.indexOf("successfully")==-1)
1070
      {
1071
        response.setContentType("text/xml");
1072 2717 tao
        out.println("<error>Couldn't pass the trust test "+test+" </error>");
1073 1292 tao
        out.close();
1074 1097 tao
        return;
1075
      }
1076 2286 tao
1077 536 berkley
      String docid = ((String[])(params.get("docid")))[0];
1078 2286 tao
1079 1217 tao
      DocumentImpl di = new DocumentImpl(docid);
1080 534 berkley
      response.setContentType("text/xml");
1081 1767 tao
      out.print(di.toString(null, null, true));
1082 2286 tao
1083 584 berkley
      MetacatReplication.replLog("document " + docid + " sent");
1084 2286 tao
1085 534 berkley
    }
1086
    catch(Exception e)
1087
    {
1088 2663 sgarg
      logMetacat.error("error getting document from MetacatReplication."
1089
                          +"handlGetDocumentRequest " + e.getMessage());
1090 1099 tao
      //e.printStackTrace(System.out);
1091
      response.setContentType("text/xml");
1092 1292 tao
      out.println("<error>"+e.getMessage()+"</error>");
1093 534 berkley
    }
1094 2286 tao
1095 534 berkley
  }
1096 2286 tao
1097 573 berkley
  /**
1098 583 berkley
   * Sends a list of all of the documents on this sever along with their
1099 2286 tao
   * revision numbers.
1100 583 berkley
   * The format is:
1101
   * <!ELEMENT replication (server, updates)>
1102
   * <!ELEMENT server (#PCDATA)>
1103 2597 tao
   * <!ELEMENT updates ((updatedDocument | deleteDocument | revisionDocument)*)>
1104 1020 tao
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
1105 1035 tao
   * <!ELEMENT deletedDocument (docid, rev)>
1106 2597 tao
   * <!ELEMENT revisionDocument (docid, rev, datafile*)>
1107 583 berkley
   * <!ELEMENT docid (#PCDATA)>
1108
   * <!ELEMENT rev (#PCDATA)>
1109 1020 tao
   * <!ELEMENT datafile (#PCDATA)>
1110 583 berkley
   * note that the rev in deletedDocument is always empty.  I just left
1111
   * it in there to make the parser implementation easier.
1112 573 berkley
   */
1113 2286 tao
  private void handleUpdateRequest(PrintWriter out, Hashtable params,
1114 577 berkley
                                    HttpServletResponse response)
1115
  {
1116 2286 tao
    // Checked out DBConnection
1117 1217 tao
    DBConnection dbConn = null;
1118 1292 tao
    // DBConenction serial number when checked it out
1119 1217 tao
    int serialNumber = -1;
1120
    PreparedStatement pstmt = null;
1121 1292 tao
    // Server list to store server info of xml_replication table
1122
    ReplicationServerList serverList = null;
1123 2286 tao
1124 577 berkley
    try
1125
    {
1126 1292 tao
      // Check out a DBConnection from pool
1127
      dbConn=DBConnectionPool.
1128
                  getDBConnection("MetacatReplication.handleUpdateRequest");
1129
      serialNumber=dbConn.getCheckOutSerialNumber();
1130
      // Create a server list from xml_replication table
1131
      serverList = new ReplicationServerList();
1132 2286 tao
1133 1292 tao
      // Get remote server name from param
1134
      String server = ((String[])params.get("server"))[0];
1135
      // If no servr name in param, return a error
1136
      if ( server == null || server.equals(""))
1137
      {
1138
        response.setContentType("text/xml");
1139
        out.println("<error>Request didn't specify server name</error>");
1140
        out.close();
1141
        return;
1142
      }//if
1143 2286 tao
1144 1101 tao
      //try to open a https stream to test if the request server's public key
1145
      //in the key store, this is security issue
1146
      URL u = new URL("https://" + server + "?server="
1147
                +util.getLocalReplicationServerName()
1148
                +"&action=test");
1149
      String test = MetacatReplication.getURLContent(u);
1150
      //couldn't pass the test
1151
      if (test.indexOf("successfully")==-1)
1152
      {
1153
        response.setContentType("text/xml");
1154
        out.println("<error>Couldn't pass the trust test</error>");
1155 1292 tao
        out.close();
1156 1101 tao
        return;
1157
      }
1158 2286 tao
1159
1160 1292 tao
      // Check if local host configure to replicate xml documents to remote
1161
      // server. If not send back a error message
1162
      if (!serverList.getReplicationValue(server))
1163
      {
1164
        response.setContentType("text/xml");
1165
        out.println
1166
        ("<error>Configuration not allow to replicate document to you</error>");
1167
        out.close();
1168
        return;
1169
      }//if
1170 2286 tao
1171 1292 tao
      // Store the sql command
1172 577 berkley
      StringBuffer docsql = new StringBuffer();
1173 2597 tao
      StringBuffer revisionSql = new StringBuffer();
1174 1292 tao
      // Stroe the docid list
1175 577 berkley
      StringBuffer doclist = new StringBuffer();
1176 1292 tao
      // Store the deleted docid list
1177
      StringBuffer delsql = new StringBuffer();
1178
      // Store the data set file
1179 625 berkley
      Vector packageFiles = new Vector();
1180 2286 tao
1181 1292 tao
      // Append local server's name and replication servlet to doclist
1182 577 berkley
      doclist.append("<?xml version=\"1.0\"?><replication>");
1183 2581 tao
      doclist.append("<server>").append(util.getLocalReplicationServerName());
1184
      //doclist.append(util.getOption("replicationpath"));
1185 577 berkley
      doclist.append("</server><updates>");
1186 2286 tao
1187 1292 tao
      // Get correct docid that reside on this server according the requesting
1188
      // server's replicate and data replicate value in xml_replication table
1189 2724 tao
      docsql.append(dbAdapter.getReplicationDocumentListSQL());
1190
      //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)) ");
1191 2597 tao
      revisionSql.append("select docid, rev, doctype from xml_revisions ");
1192 1292 tao
      // If the localhost is not a hub to the remote server, only replicate
1193
      // the docid' which home server is local host (server_location =1)
1194
      if (!serverList.getHubValue(server))
1195 1042 tao
      {
1196 2724 tao
    	String serverLocationDoc = " and a.server_location = 1";
1197 2719 tao
        String serverLocationRev = "where server_location = 1";
1198
        docsql.append(serverLocationDoc);
1199
        revisionSql.append(serverLocationRev);
1200 1042 tao
      }
1201 2663 sgarg
      logMetacat.info("Doc sql: "+docsql.toString());
1202 2286 tao
1203 1292 tao
      // Get any deleted documents
1204 577 berkley
      delsql.append("select distinct docid from ");
1205
      delsql.append("xml_revisions where docid not in (select docid from ");
1206 1042 tao
      delsql.append("xml_documents) ");
1207 1292 tao
      // If the localhost is not a hub to the remote server, only replicate
1208
      // the docid' which home server is local host (server_location =1)
1209
      if (!serverList.getHubValue(server))
1210 1042 tao
      {
1211
        delsql.append("and server_location = 1");
1212
      }
1213 2663 sgarg
      logMetacat.info("Deleted sql: "+delsql.toString());
1214 2286 tao
1215
1216
1217 1292 tao
      // Get docid list of local host
1218 1217 tao
      pstmt = dbConn.prepareStatement(docsql.toString());
1219 577 berkley
      pstmt.execute();
1220
      ResultSet rs = pstmt.getResultSet();
1221
      boolean tablehasrows = rs.next();
1222 1035 tao
      //If metacat configed to replicate data file
1223 1292 tao
      //if ((util.getOption("replicationsenddata")).equals("on"))
1224 2597 tao
      boolean replicateData = serverList.getDataReplicationValue(server);
1225
      if (replicateData)
1226 577 berkley
      {
1227 1020 tao
        while(tablehasrows)
1228
        {
1229
          String recordDoctype = rs.getString(3);
1230 1035 tao
          Vector packagedoctypes = MetaCatUtil.getOptionList(
1231
                                     MetaCatUtil.getOption("packagedoctype"));
1232 1292 tao
          //if this is a package file, put it at the end
1233
          //because if a package file is read before all of the files it
1234
          //refers to are loaded then there is an error
1235 1768 tao
          if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1236 2286 tao
          {
1237 1292 tao
              //If this is not data file
1238 1035 tao
              if (!recordDoctype.equals("BIN"))
1239
              {
1240
                //for non-data file document
1241
                doclist.append("<updatedDocument>");
1242
                doclist.append("<docid>").append(rs.getString(1));
1243
                doclist.append("</docid><rev>").append(rs.getInt(2));
1244
                doclist.append("</rev>");
1245
                doclist.append("</updatedDocument>");
1246 1292 tao
              }//if
1247 1035 tao
              else
1248
              {
1249
                //for data file document, in datafile attributes
1250
                //we put "datafile" value there
1251
                doclist.append("<updatedDocument>");
1252
                doclist.append("<docid>").append(rs.getString(1));
1253
                doclist.append("</docid><rev>").append(rs.getInt(2));
1254
                doclist.append("</rev>");
1255
                doclist.append("<datafile>");
1256
                doclist.append(MetaCatUtil.getOption("datafileflag"));
1257
                doclist.append("</datafile>");
1258
                doclist.append("</updatedDocument>");
1259 2286 tao
              }//else
1260 1292 tao
          }//if packagedoctpes
1261 1035 tao
          else
1262
          { //the package files are saved to be put into the xml later.
1263
              Vector v = new Vector();
1264
              v.add(new String(rs.getString(1)));
1265
              v.add(new Integer(rs.getInt(2)));
1266
              packageFiles.add(new Vector(v));
1267 1292 tao
          }//esle
1268 1035 tao
          tablehasrows = rs.next();
1269
        }//while
1270
      }//if
1271
      else //metacat was configured not to send data file
1272
      {
1273
        while(tablehasrows)
1274
        {
1275
          String recordDoctype = rs.getString(3);
1276 2286 tao
          if(!recordDoctype.equals("BIN"))
1277 1020 tao
          { //don't replicate data files
1278
            Vector packagedoctypes = MetaCatUtil.getOptionList(
1279 887 berkley
                                     MetaCatUtil.getOption("packagedoctype"));
1280 1768 tao
            if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1281 1020 tao
            {   //if this is a package file, put it at the end
1282
              //because if a package file is read before all of the files it
1283
              //refers to are loaded then there is an error
1284
              doclist.append("<updatedDocument>");
1285
              doclist.append("<docid>").append(rs.getString(1));
1286
              doclist.append("</docid><rev>").append(rs.getInt(2));
1287
              doclist.append("</rev>");
1288
              doclist.append("</updatedDocument>");
1289
            }
1290
            else
1291
            { //the package files are saved to be put into the xml later.
1292
              Vector v = new Vector();
1293
              v.add(new String(rs.getString(1)));
1294
              v.add(new Integer(rs.getInt(2)));
1295
              packageFiles.add(new Vector(v));
1296
            }
1297
         }//if
1298
         tablehasrows = rs.next();
1299
        }//while
1300 1035 tao
      }//else
1301 2286 tao
1302 1217 tao
      pstmt = dbConn.prepareStatement(delsql.toString());
1303
      //usage count should increas 1
1304
      dbConn.increaseUsageCount(1);
1305 2286 tao
1306 577 berkley
      pstmt.execute();
1307
      rs = pstmt.getResultSet();
1308
      tablehasrows = rs.next();
1309
      while(tablehasrows)
1310
      { //handle the deleted documents
1311
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1312
        doclist.append("</docid><rev></rev></deletedDocument>");
1313 583 berkley
        //note that rev is always empty for deleted docs
1314 577 berkley
        tablehasrows = rs.next();
1315
      }
1316 2286 tao
1317 625 berkley
      //now we can put the package files into the xml results
1318
      for(int i=0; i<packageFiles.size(); i++)
1319
      {
1320
        Vector v = (Vector)packageFiles.elementAt(i);
1321
        doclist.append("<updatedDocument>");
1322
        doclist.append("<docid>").append((String)v.elementAt(0));
1323
        doclist.append("</docid><rev>");
1324
        doclist.append(((Integer)v.elementAt(1)).intValue());
1325
        doclist.append("</rev>");
1326
        doclist.append("</updatedDocument>");
1327
      }
1328 2597 tao
      // add revision doc list
1329
      doclist.append(prepareRevisionDoc(dbConn,revisionSql.toString(),replicateData));
1330
1331 577 berkley
      doclist.append("</updates></replication>");
1332 2663 sgarg
      logMetacat.info("doclist: " + doclist.toString());
1333 667 berkley
      pstmt.close();
1334 1217 tao
      //conn.close();
1335 577 berkley
      response.setContentType("text/xml");
1336
      out.println(doclist.toString());
1337 2286 tao
1338 577 berkley
    }
1339
    catch(Exception e)
1340
    {
1341 2663 sgarg
      logMetacat.error("error in MetacatReplication." +
1342
                         "handleupdaterequest: " + e.getMessage());
1343 1101 tao
      //e.printStackTrace(System.out);
1344
      response.setContentType("text/xml");
1345 1292 tao
      out.println("<error>"+e.getMessage()+"</error>");
1346 577 berkley
    }
1347 1217 tao
    finally
1348
    {
1349
      try
1350
      {
1351
        pstmt.close();
1352
      }//try
1353
      catch (SQLException ee)
1354
      {
1355 2663 sgarg
        logMetacat.error("Error in MetacatReplication." +
1356
                "handleUpdaterequest to close pstmt: "+ee.getMessage());
1357 1217 tao
      }//catch
1358
      finally
1359
      {
1360
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1361
      }//finally
1362
    }//finally
1363 2286 tao
1364 1292 tao
  }//handlUpdateRequest
1365 2597 tao
1366
  /*
1367
   * This method will get the xml string for document in xml_revision
1368
   * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1369
   */
1370
  private String prepareRevisionDoc(DBConnection dbConn, String revSql,
1371
                            boolean replicateData) throws Exception
1372
  {
1373 2663 sgarg
      logMetacat.warn("The revision document sql is "+ revSql);
1374 2597 tao
      StringBuffer revDocList = new StringBuffer();
1375 2619 tao
      PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1376 2597 tao
      //usage count should increas 1
1377
      dbConn.increaseUsageCount(1);
1378 2286 tao
1379 2597 tao
      pstmt.execute();
1380
      ResultSet rs = pstmt.getResultSet();
1381
      boolean tablehasrows = rs.next();
1382
      while(tablehasrows)
1383
      {
1384
        String recordDoctype = rs.getString(3);
1385
1386
        //If this is data file and it isn't configured to replicate data
1387
        if (recordDoctype.equals("BIN") && !replicateData)
1388
        {
1389
            // do nothing
1390
            continue;
1391
        }
1392
        else
1393
        {
1394
1395
            revDocList.append("<revisionDocument>");
1396
            revDocList.append("<docid>").append(rs.getString(1));
1397
            revDocList.append("</docid><rev>").append(rs.getInt(2));
1398
            revDocList.append("</rev>");
1399
            // data file
1400
            if (recordDoctype.equals("BIN"))
1401
            {
1402
                revDocList.append("<datafile>");
1403
                revDocList.append(MetaCatUtil.getOption("datafileflag"));
1404
                revDocList.append("</datafile>");
1405
            }
1406 2619 tao
            revDocList.append("</revisionDocument>");
1407 2597 tao
1408
         }//else
1409 2619 tao
         tablehasrows = rs.next();
1410 2597 tao
      }
1411 2619 tao
      //System.out.println("The revision list is"+ revDocList.toString());
1412 2597 tao
      return revDocList.toString();
1413
  }
1414
1415 577 berkley
  /**
1416 590 berkley
   * Returns the xml_catalog table encoded in xml
1417
   */
1418
  public static String getCatalogXML()
1419
  {
1420
    return handleGetCatalogRequest(null, null, null, false);
1421
  }
1422 2286 tao
1423 590 berkley
  /**
1424
   * Sends the contents of the xml_catalog table encoded in xml
1425
   * The xml format is:
1426
   * <!ELEMENT xml_catalog (row*)>
1427
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1428
   *                system_id)>
1429
   * All of the sub elements of row are #PCDATA
1430 2286 tao
1431 590 berkley
   * If printFlag == false then do not print to out.
1432
   */
1433 2286 tao
  private static String handleGetCatalogRequest(PrintWriter out,
1434 590 berkley
                                                Hashtable params,
1435
                                                HttpServletResponse response,
1436
                                                boolean printFlag)
1437
  {
1438 1217 tao
    DBConnection dbConn = null;
1439
    int serialNumber = -1;
1440 667 berkley
    PreparedStatement pstmt = null;
1441 590 berkley
    try
1442 2286 tao
    {
1443 1217 tao
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1444
                                                "handleGetCatalogRequest");*/
1445
      dbConn=DBConnectionPool.
1446
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1447
      serialNumber=dbConn.getCheckOutSerialNumber();
1448
      pstmt = dbConn.prepareStatement("select entry_type, " +
1449 590 berkley
                              "source_doctype, target_doctype, public_id, " +
1450
                              "system_id from xml_catalog");
1451
      pstmt.execute();
1452
      ResultSet rs = pstmt.getResultSet();
1453
      boolean tablehasrows = rs.next();
1454
      StringBuffer sb = new StringBuffer();
1455
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1456
      while(tablehasrows)
1457
      {
1458
        sb.append("<row><entry_type>").append(rs.getString(1));
1459
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1460
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1461
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1462
        sb.append("</public_id><system_id>").append(rs.getString(5));
1463
        sb.append("</system_id></row>");
1464 2286 tao
1465 590 berkley
        tablehasrows = rs.next();
1466
      }
1467
      sb.append("</xml_catalog>");
1468 1217 tao
      //conn.close();
1469 590 berkley
      if(printFlag)
1470
      {
1471
        response.setContentType("text/xml");
1472
        out.println(sb.toString());
1473
      }
1474 667 berkley
      pstmt.close();
1475 590 berkley
      return sb.toString();
1476
    }
1477
    catch(Exception e)
1478
    {
1479 2286 tao
1480 2663 sgarg
      logMetacat.error("error in MetacatReplication.handleGetCatalogRequest:"+
1481
                          e.getMessage());
1482 590 berkley
      e.printStackTrace(System.out);
1483 1292 tao
      if(printFlag)
1484
      {
1485
        out.println("<error>"+e.getMessage()+"</error>");
1486
      }
1487 590 berkley
    }
1488 1217 tao
    finally
1489
    {
1490
      try
1491
      {
1492
        pstmt.close();
1493
      }//try
1494
      catch (SQLException ee)
1495
      {
1496 2663 sgarg
        logMetacat.error("Error in MetacatReplication.handleGetCatalogRequest: "
1497
           +ee.getMessage());
1498 1217 tao
      }//catch
1499
      finally
1500
      {
1501
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1502
      }//finally
1503
    }//finally
1504 2286 tao
1505 590 berkley
    return null;
1506
  }
1507 2286 tao
1508 590 berkley
  /**
1509 568 berkley
   * Sends the current system date to the remote server.  Using this action
1510 2286 tao
   * for replication gets rid of any problems with syncronizing clocks
1511 568 berkley
   * because a time specific to a document is always kept on its home server.
1512
   */
1513 2286 tao
  private void handleGetTimeRequest(PrintWriter out, Hashtable params,
1514 568 berkley
                                    HttpServletResponse response)
1515
  {
1516 1752 tao
    SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yy HH:mm:ss");
1517 568 berkley
    java.util.Date localtime = new java.util.Date();
1518
    String dateString = formatter.format(localtime);
1519
    response.setContentType("text/xml");
1520 2286 tao
1521 568 berkley
    out.println("<timestamp>" + dateString + "</timestamp>");
1522
  }
1523 2286 tao
1524 568 berkley
  /**
1525 2286 tao
   * this method handles the timeout for a file lock.  when a lock is
1526 583 berkley
   * granted it is granted for 30 seconds.  When this thread runs out
1527
   * it deletes the docid from the queue, thus eliminating the lock.
1528 561 berkley
   */
1529
  public void run()
1530
  {
1531
    try
1532
    {
1533 2663 sgarg
      logMetacat.info("thread started for docid: " +
1534
                               (String)fileLocks.elementAt(0));
1535 2286 tao
1536 561 berkley
      Thread.sleep(30000); //the lock will expire in 30 seconds
1537 2663 sgarg
      logMetacat.info("thread for docid: " +
1538 2286 tao
                             (String)fileLocks.elementAt(fileLocks.size() - 1) +
1539 2663 sgarg
                              " exiting.");
1540 2286 tao
1541 561 berkley
      fileLocks.remove(fileLocks.size() - 1);
1542 568 berkley
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1543 561 berkley
      //in the vector, the first one inserted will be removed.
1544
    }
1545
    catch(Exception e)
1546
    {
1547 2663 sgarg
      logMetacat.error("error in file lock thread from " +
1548
                                "MetacatReplication.run: " + e.getMessage());
1549 561 berkley
    }
1550
  }
1551 2286 tao
1552 561 berkley
  /**
1553
   * Returns the name of a server given a serverCode
1554
   * @param serverCode the serverid of the server
1555
   * @return the servername or null if the specified serverCode does not
1556
   *         exist.
1557
   */
1558 1292 tao
  public static String getServerNameForServerCode(int serverCode)
1559 561 berkley
  {
1560 569 berkley
    //System.out.println("serverid: " + serverCode);
1561 1217 tao
    DBConnection dbConn = null;
1562
    int serialNumber = -1;
1563
    PreparedStatement pstmt = null;
1564 561 berkley
    try
1565
    {
1566 1217 tao
      dbConn=DBConnectionPool.
1567
                  getDBConnection("MetacatReplication.getServer");
1568
      serialNumber=dbConn.getCheckOutSerialNumber();
1569 569 berkley
      String sql = new String("select server from " +
1570 2286 tao
                              "xml_replication where serverid = " +
1571 561 berkley
                              serverCode);
1572 1217 tao
      pstmt = dbConn.prepareStatement(sql);
1573 569 berkley
      //System.out.println("getserver sql: " + sql);
1574 561 berkley
      pstmt.execute();
1575
      ResultSet rs = pstmt.getResultSet();
1576
      boolean tablehasrows = rs.next();
1577
      if(tablehasrows)
1578
      {
1579 569 berkley
        //System.out.println("server: " + rs.getString(1));
1580 561 berkley
        return rs.getString(1);
1581
      }
1582 2286 tao
1583 1217 tao
      //conn.close();
1584 561 berkley
    }
1585
    catch(Exception e)
1586
    {
1587 2286 tao
      System.out.println("Error in MetacatReplication.getServer: " +
1588 561 berkley
                          e.getMessage());
1589
    }
1590 1217 tao
    finally
1591
    {
1592
      try
1593
      {
1594
        pstmt.close();
1595
      }//try
1596
      catch (SQLException ee)
1597
      {
1598 2663 sgarg
        logMetacat.error("Error in MetacactReplication.getserver: "+
1599
                                    ee.getMessage());
1600 1217 tao
      }//catch
1601
      finally
1602
      {
1603
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1604
      }//fianlly
1605
    }//finally
1606 2286 tao
1607
1608
1609 561 berkley
    return null;
1610
      //return null if the server does not exist
1611
  }
1612 2286 tao
1613 569 berkley
  /**
1614
   * Returns a server code given a server name
1615
   * @param server the name of the server
1616
   * @return integer > 0 representing the code of the server, 0 if the server
1617
   *  does not exist.
1618
   */
1619 1292 tao
  public static int getServerCodeForServerName(String server) throws Exception
1620 569 berkley
  {
1621 1217 tao
    DBConnection dbConn = null;
1622
    int serialNumber = -1;
1623 667 berkley
    PreparedStatement pstmt = null;
1624 837 bojilova
    int serverCode = 0;
1625
1626
    try {
1627
1628 1217 tao
      //conn = util.openDBConnection();
1629
      dbConn=DBConnectionPool.
1630
                  getDBConnection("MetacatReplication.getServerCode");
1631
      serialNumber=dbConn.getCheckOutSerialNumber();
1632
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1633 837 bojilova
                                    "WHERE server LIKE '" + server + "'");
1634 569 berkley
      pstmt.execute();
1635
      ResultSet rs = pstmt.getResultSet();
1636
      boolean tablehasrows = rs.next();
1637 2286 tao
      if ( tablehasrows ) {
1638 837 bojilova
        serverCode = rs.getInt(1);
1639 667 berkley
        pstmt.close();
1640 1217 tao
        //conn.close();
1641 837 bojilova
        return serverCode;
1642 569 berkley
      }
1643 2286 tao
1644 837 bojilova
    } catch(Exception e) {
1645
      throw e;
1646
1647
    } finally {
1648 2286 tao
      try
1649 1217 tao
      {
1650 667 berkley
        pstmt.close();
1651 1217 tao
        //conn.close();
1652
       }//try
1653 2286 tao
       catch(Exception ee)
1654 1217 tao
       {
1655 2663 sgarg
         logMetacat.error("Error in MetacatReplicatio.getServerCode: "
1656
                                  +ee.getMessage());
1657 2286 tao
1658 1217 tao
       }//catch
1659
       finally
1660
       {
1661
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1662
       }//finally
1663
    }//finally
1664 2286 tao
1665 837 bojilova
    return serverCode;
1666 569 berkley
  }
1667 2286 tao
1668 569 berkley
  /**
1669 1292 tao
   * Method to get a host server information for given docid
1670
   * @param conn a connection to the database
1671
   */
1672
  public static Hashtable getHomeServerInfoForDocId(String docId)
1673
  {
1674
    Hashtable sl = new Hashtable();
1675
    DBConnection dbConn = null;
1676
    int serialNumber = -1;
1677
    //MetaCatUtil ut=new MetaCatUtil();
1678
    docId=MetaCatUtil.getDocIdFromString(docId);
1679
    PreparedStatement pstmt=null;
1680
    int serverLocation;
1681
    try
1682
    {
1683
      //get conection
1684
      dbConn=DBConnectionPool.
1685
                  getDBConnection("ReplicationHandler.getHomeServer");
1686
      serialNumber=dbConn.getCheckOutSerialNumber();
1687
      //get a server location from xml_document table
1688
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
1689
                                            +"where docid = ?");
1690
      pstmt.setString(1, docId);
1691
      pstmt.execute();
1692
      ResultSet serverName = pstmt.getResultSet();
1693
      //get a server location
1694
      if(serverName.next())
1695
      {
1696
        serverLocation=serverName.getInt(1);
1697
        pstmt.close();
1698
      }
1699
      else
1700
      {
1701
        pstmt.close();
1702
        //ut.returnConnection(conn);
1703
        return null;
1704
      }
1705
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
1706
                        "from xml_replication where serverid = ?");
1707
      //increase usage count
1708
      dbConn.increaseUsageCount(1);
1709
      pstmt.setInt(1, serverLocation);
1710
      pstmt.execute();
1711
      ResultSet rs = pstmt.getResultSet();
1712
      boolean tableHasRows = rs.next();
1713
      if (tableHasRows)
1714
      {
1715 2286 tao
1716 1292 tao
          String server = rs.getString(1);
1717
          String last_checked = rs.getString(2);
1718
          if(!server.equals("localhost"))
1719
          {
1720
            sl.put(server, last_checked);
1721
          }
1722 2286 tao
1723 1292 tao
      }
1724
      else
1725
      {
1726
        pstmt.close();
1727
        //ut.returnConnection(conn);
1728
        return null;
1729
      }
1730
      pstmt.close();
1731
    }
1732
    catch(Exception e)
1733
    {
1734
      System.out.println("error in replicationHandler.getHomeServer(): " +
1735
                         e.getMessage());
1736
    }
1737
    finally
1738
    {
1739
      try
1740
      {
1741
        pstmt.close();
1742
        //ut.returnConnection(conn);
1743
      }
1744
      catch (Exception ee)
1745
      {
1746 2663 sgarg
        logMetacat.error("Eror irn rplicationHandler.getHomeServer() "+
1747
                          "to close pstmt: "+ee.getMessage());
1748 1292 tao
      }
1749
      finally
1750
      {
1751
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1752
      }
1753 2286 tao
1754 1292 tao
    }//finally
1755
    return sl;
1756
  }
1757 2286 tao
1758 1292 tao
  /**
1759
   * Returns a home server location  given a accnum
1760
   * @param accNum , given accNum for a document
1761 2286 tao
   *
1762 1292 tao
   */
1763
  public static int getHomeServerCodeForDocId(String accNum) throws Exception
1764
  {
1765
    DBConnection dbConn = null;
1766
    int serialNumber = -1;
1767
    PreparedStatement pstmt = null;
1768
    int serverCode = 1;
1769
    //MetaCatUtil ut = new MetaCatUtil();
1770
    String docId=MetaCatUtil.getDocIdFromString(accNum);
1771
1772 2286 tao
    try
1773 1292 tao
    {
1774
1775
      // Get DBConnection
1776
      dbConn=DBConnectionPool.
1777
                  getDBConnection("ReplicationHandler.getServerLocation");
1778
      serialNumber=dbConn.getCheckOutSerialNumber();
1779 2286 tao
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1780 1292 tao
                              + "WHERE docid LIKE '" + docId + "'");
1781
      pstmt.execute();
1782
      ResultSet rs = pstmt.getResultSet();
1783
      boolean tablehasrows = rs.next();
1784
      //If a document is find, return the server location for it
1785 2286 tao
      if ( tablehasrows )
1786
      {
1787 1292 tao
        serverCode = rs.getInt(1);
1788
        pstmt.close();
1789
        //conn.close();
1790
        return serverCode;
1791
      }
1792
      //if couldn't find in xml_documents table, we think server code is 1
1793
      //(this is new document)
1794
      else
1795
      {
1796
        pstmt.close();
1797
        //conn.close();
1798
        return serverCode;
1799
      }
1800 2286 tao
1801
    }
1802
    catch(Exception e)
1803 1292 tao
    {
1804 2286 tao
1805 1292 tao
      throw e;
1806
1807 2286 tao
    }
1808
    finally
1809 1292 tao
    {
1810 2286 tao
      try
1811 1292 tao
      {
1812
        pstmt.close();
1813
        //conn.close();
1814 2286 tao
1815
      }
1816
      catch(Exception ee)
1817 1292 tao
      {
1818 2663 sgarg
        logMetacat.error("Erorr in Replication.getServerLocation "+
1819
                     "to close pstmt"+ee.getMessage());
1820 1292 tao
      }
1821
      finally
1822
      {
1823
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1824
      }//finally
1825
    }//finally
1826
   //return serverCode;
1827
  }
1828 2286 tao
1829
1830
1831 1292 tao
  /**
1832 569 berkley
   * This method returns the content of a url
1833
   * @param u the url to return the content from
1834
   * @return a string representing the content of the url
1835
   * @throws java.io.IOException
1836
   */
1837
  public static String getURLContent(URL u) throws java.io.IOException
1838
  {
1839
    char istreamChar;
1840
    int istreamInt;
1841 2663 sgarg
    logMetacat.info("Before open the stream"+u.toString());
1842 1606 tao
    InputStream input = u.openStream();
1843 2663 sgarg
    logMetacat.info("Afetr open the stream"+u.toString());
1844 1606 tao
    InputStreamReader istream = new InputStreamReader(input);
1845 569 berkley
    StringBuffer serverResponse = new StringBuffer();
1846
    while((istreamInt = istream.read()) != -1)
1847
    {
1848
      istreamChar = (char)istreamInt;
1849
      serverResponse.append(istreamChar);
1850
    }
1851 1606 tao
    istream.close();
1852
    input.close();
1853 2286 tao
1854 569 berkley
    return serverResponse.toString();
1855
  }
1856 2286 tao
1857 584 berkley
  /**
1858 2286 tao
   * Method for writing replication messages to a log file specified in
1859 584 berkley
   * metacat.properties
1860
   */
1861
  public static void replLog(String message)
1862
  {
1863
    try
1864
    {
1865
      FileOutputStream fos = new FileOutputStream(
1866
                                 util.getOption("replicationlog"), true);
1867
      PrintWriter pw = new PrintWriter(fos);
1868
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1869
      java.util.Date localtime = new java.util.Date();
1870
      String dateString = formatter.format(localtime);
1871
      dateString += " :: " + message;
1872
      //time stamp each entry
1873
      pw.println(dateString);
1874
      pw.flush();
1875
    }
1876
    catch(Exception e)
1877
    {
1878 675 berkley
      System.out.println("error writing to replication log from " +
1879
                         "MetacatReplication.replLog: " + e.getMessage());
1880 595 berkley
      //e.printStackTrace(System.out);
1881 584 berkley
    }
1882
  }
1883 2286 tao
1884 629 berkley
  /**
1885 2286 tao
   * Method for writing replication messages to a log file specified in
1886 1583 tao
   * metacat.properties
1887
   */
1888
  public static void replErrorLog(String message)
1889
  {
1890
    try
1891
    {
1892
      FileOutputStream fos = new FileOutputStream(
1893
                                 util.getOption("replicationerrorlog"), true);
1894
      PrintWriter pw = new PrintWriter(fos);
1895
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1896
      java.util.Date localtime = new java.util.Date();
1897
      String dateString = formatter.format(localtime);
1898
      dateString += " :: " + message;
1899
      //time stamp each entry
1900
      pw.println(dateString);
1901
      pw.flush();
1902
    }
1903
    catch(Exception e)
1904
    {
1905
      System.out.println("error writing to replication log from " +
1906
                         "MetacatReplication.replLog: " + e.getMessage());
1907
      //e.printStackTrace(System.out);
1908
    }
1909
  }
1910 2286 tao
1911 1583 tao
  /**
1912 629 berkley
   * Returns true if the replicate field for server in xml_replication is 1.
1913
   * Returns false otherwise
1914
   */
1915
  public static boolean replToServer(String server)
1916
  {
1917 1217 tao
    DBConnection dbConn = null;
1918
    int serialNumber = -1;
1919 667 berkley
    PreparedStatement pstmt = null;
1920 629 berkley
    try
1921
    {
1922 1217 tao
      dbConn=DBConnectionPool.
1923
                  getDBConnection("MetacatReplication.repltoServer");
1924
      serialNumber=dbConn.getCheckOutSerialNumber();
1925 2286 tao
      pstmt = dbConn.prepareStatement("select replicate from " +
1926 667 berkley
                                    "xml_replication where server like '" +
1927
                                     server + "'");
1928 629 berkley
      pstmt.execute();
1929
      ResultSet rs = pstmt.getResultSet();
1930
      boolean tablehasrows = rs.next();
1931
      if(tablehasrows)
1932
      {
1933
        int i = rs.getInt(1);
1934
        if(i == 1)
1935
        {
1936 667 berkley
          pstmt.close();
1937 1217 tao
          //conn.close();
1938 629 berkley
          return true;
1939
        }
1940
        else
1941
        {
1942 667 berkley
          pstmt.close();
1943 1217 tao
          //conn.close();
1944 629 berkley
          return false;
1945
        }
1946
      }
1947
    }
1948
    catch(Exception e)
1949
    {
1950 2286 tao
      System.out.println("error in MetacatReplication.replToServer: " +
1951 675 berkley
                         e.getMessage());
1952 629 berkley
    }
1953 667 berkley
    finally
1954
    {
1955
      try
1956
      {
1957
        pstmt.close();
1958 1217 tao
        //conn.close();
1959
      }//try
1960 667 berkley
      catch(Exception ee)
1961 1217 tao
      {
1962 2663 sgarg
        logMetacat.error("Error in MetacatReplication.replToServer: "
1963
                                  +ee.getMessage());
1964 1217 tao
      }//catch
1965
      finally
1966
      {
1967
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1968
      }//finally
1969
    }//finally
1970 629 berkley
    return false;
1971
    //the default if this server does not exist is to not replicate to it.
1972
  }
1973 2286 tao
1974
1975 522 berkley
}