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