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