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 4449 leinfelder
      //try this independently so we can set
682
      Exception writeException = null;
683
      try {
684
	      wrapper.writeReplication(dbConn, new StringReader(xmldoc), null, null,
685
	                               dbaction, docid, user, null, homeServer,
686
	                               server, createdDate, updatedDate);
687
      }
688
      catch (Exception e) {
689
    	  writeException = e;
690
      }
691 3230 tao
692 4449 leinfelder
      //process extra access rules before dealing with the write exception (doc exist already)
693 4419 leinfelder
      Vector accessControlList = (Vector) docinfoHash.get("accessControl");
694
      if (accessControlList != null) {
695
    	  for (int i = 0; i < accessControlList.size(); i++) {
696
        	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
697 4450 leinfelder
        	  if (!acfsf.accessControlExists()) {
698
	        	  acfsf.insertPermissions();
699
	        	  MetacatReplication.replLog("document " + docid + " permissions added to DB");
700
        	  }
701 4419 leinfelder
          }
702
      }
703
704 4449 leinfelder
      if (writeException != null) {
705
    	  throw writeException;
706
      }
707
708 584 berkley
      MetacatReplication.replLog("document " + docid + " added to DB with " +
709
                                 "action " + dbaction);
710 3233 tao
      EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
711 1292 tao
    }//try
712 2286 tao
    catch(Exception e)
713 1292 tao
    {
714 2286 tao
      MetacatReplication.replErrorLog("document " + docid +
715 1583 tao
                                      " failed to added to DB with " +
716
                                      "action " + dbaction + " because "+
717
                                       e.getMessage());
718 2663 sgarg
      logMetacat.error("ERROR in MetacatReplication.handleForceReplicate" +
719
                         "Request(): " + e.getMessage());
720 2286 tao
721 1292 tao
    }//catch
722 1217 tao
    finally
723
    {
724 1292 tao
      // Return the checked out DBConnection
725 1217 tao
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
726
    }//finally
727 574 berkley
  }
728 2286 tao
729 2298 tao
/*
730
 * when a forcereplication delete request comes in, local host will delete this
731
 * document
732
 */
733
private void handleForceReplicateDeleteRequest(PrintWriter out, Hashtable params,
734 3233 tao
                                         HttpServletResponse response, HttpServletRequest request)
735 2298 tao
{
736
  String server = ((String[])params.get("server"))[0]; // the server that
737
  String docid = ((String[])params.get("docid"))[0]; // sent the document
738
  try
739
  {
740
    MetacatReplication.replLog("force replication delete request from " + server);
741
    MetacatReplication.replLog("force replication delete docid " + docid);
742 2663 sgarg
    logMetacat.info("Force replication delete request from: "+ server);
743
    logMetacat.info("Force replication delete docid: "+docid);
744 3230 tao
    DocumentImpl.delete(docid, null, null, server);
745 2298 tao
    MetacatReplication.replLog("document " + docid + " was successfully deleted ");
746 3233 tao
    EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, "delete");
747 2663 sgarg
    logMetacat.info("document " + docid + " was successfully deleted ");
748 2298 tao
  }
749
  catch(Exception e)
750
  {
751
    MetacatReplication.replErrorLog("document " + docid +
752
                                    " failed to delete because "+
753
                                     e.getMessage());
754 2663 sgarg
    logMetacat.error("ERROR in MetacatReplication.handleForceDeleteReplicate" +
755
                       "Request(): " + e.getMessage());
756 2298 tao
757
  }//catch
758
759
}
760
761
762 561 berkley
  /**
763 2286 tao
   * when a forcereplication data file request comes in, local host sends a
764
   * readdata request to the requesting server (remote server) for the specified
765 1023 tao
   * docid. Then store it in local database and file system
766
   */
767 3233 tao
  private void handleForceReplicateDataFileRequest(Hashtable params, HttpServletRequest request)
768 1023 tao
  {
769 2286 tao
770 1023 tao
    //make sure there is some parameters
771
    if(params.isEmpty())
772
    {
773
      return;
774
    }
775 2286 tao
    // Get remote server
776
    String server = ((String[])params.get("server"))[0];
777 1292 tao
    // the docid should include rev number
778 2286 tao
    String docid = ((String[])params.get("docid"))[0];
779 1292 tao
    // Make sure there is a docid and server
780
    if (docid==null || server==null || server.equals(""))
781 1023 tao
    {
782 2663 sgarg
      logMetacat.error("Didn't specify docid or server for replication");
783 1023 tao
      return;
784
    }
785 2286 tao
786 1292 tao
    // Overide or not
787 1023 tao
    boolean override = false;
788 1292 tao
    // dbaction - update or insert
789 1023 tao
    String dbaction=null;
790 2286 tao
791
    try
792 1023 tao
    {
793 1292 tao
      //docid was switch to two parts uinque code and rev
794 2650 tao
      //String uniqueCode=MetaCatUtil.getDocIdFromString(docid);
795
      //int rev=MetaCatUtil.getVersionFromString(docid);
796 2286 tao
      if(params.containsKey("dbaction"))
797 1023 tao
      {
798
        dbaction = ((String[])params.get("dbaction"))[0];
799
      }
800
      else//default value is update
801
      {
802
        dbaction = "update";
803
      }
804 2286 tao
805
      MetacatReplication.replLog("force replication request from " + server);
806 2663 sgarg
      logMetacat.info("Force replication request from: "+ server);
807
      logMetacat.info("Force replication docid: "+docid);
808
      logMetacat.info("Force replication action: "+dbaction);
809 1023 tao
      // get the document info from server
810 2286 tao
      URL docinfourl = new URL("https://" + server +
811 4080 daigle
                               "?server="+MetaCatUtil.getLocalReplicationServerName()
812 2650 tao
                               +"&action=getdocumentinfo&docid=" + docid);
813 2286 tao
814 1023 tao
      String docInfoStr = MetacatReplication.getURLContent(docinfourl);
815
816
      //dih is the parser for the docinfo xml format
817
      DocInfoHandler dih = new DocInfoHandler();
818
      XMLReader docinfoParser = ReplicationHandler.initParser(dih);
819
      docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
820
      Hashtable docinfoHash = dih.getDocInfo();
821
      String user = (String)docinfoHash.get("user_owner");
822 2286 tao
823 1023 tao
      String docName = (String)docinfoHash.get("docname");
824 2286 tao
825 1023 tao
      String docType = (String)docinfoHash.get("doctype");
826 2286 tao
827 1065 tao
      String docHomeServer= (String)docinfoHash.get("home_server");
828 2624 tao
829
      String createdDate = (String)docinfoHash.get("date_created");
830
831
      String updatedDate = (String)docinfoHash.get("date_updated");
832 2663 sgarg
      logMetacat.info("docHomeServer of datafile: "+docHomeServer);
833 2286 tao
834
835
836 1023 tao
      //if action is delete, we don't delete the data file. Just archieve
837
      //the xml_documents
838 2298 tao
      /*if (dbaction.equals("delete"))
839 1023 tao
      {
840 1217 tao
        //conn = util.getConnection();
841
        DocumentImpl.delete(docid,user,null);
842
        //util.returnConnection(conn);
843 2298 tao
      }*/
844 1031 tao
      //To data file insert or update is same
845 2298 tao
      if (dbaction.equals("insert")||dbaction.equals("update"))
846 1023 tao
      {
847
        //Get data file and store it into local file system.
848
        // sending back readdata request to server
849
        URL url = new URL("https://" + server + "?server="
850 4080 daigle
                +MetaCatUtil.getLocalReplicationServerName()
851 1023 tao
                +"&action=readdata&docid=" + docid);
852 4080 daigle
        String datafilePath = PropertyService.getProperty("application.datafilepath");
853 4449 leinfelder
854
        Exception writeException = null;
855 1031 tao
        //register data file into xml_documents table and wite data file
856
        //into file system
857 4449 leinfelder
        try {
858
        	DocumentImpl.writeDataFileInReplication(url.openStream(), datafilePath,
859 2608 tao
                            docName, docType, docid, user,docHomeServer,server,
860 3230 tao
                            DocumentImpl.DOCUMENTTABLE, false, createdDate, updatedDate);
861 4449 leinfelder
        }
862
        catch (Exception e) {
863
        	writeException = e;
864
		}
865 4419 leinfelder
        //process extra access rules
866
        Vector accessControlList = (Vector) docinfoHash.get("accessControl");
867
        if (accessControlList != null) {
868
      	  for (int i = 0; i < accessControlList.size(); i++) {
869
          	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
870 4450 leinfelder
          	  if (!acfsf.accessControlExists()) {
871
          		  acfsf.insertPermissions();
872
          		  MetacatReplication.replLog("datafile " + docid + " permissions added to DB");
873
          	  }
874 4419 leinfelder
            }
875
        }
876
877 4449 leinfelder
        if (writeException != null) {
878
        	throw writeException;
879
        }
880
881
        //false means non-timed replication
882 3233 tao
        MetacatReplication.replLog("datafile " + docid + " added to DB with " +
883
                "action " + dbaction);
884
        EventLog.getInstance().log(request.getRemoteAddr(), REPLICATIONUSER, docid, dbaction);
885 1023 tao
     }
886 3233 tao
887 2286 tao
    }
888
    catch(Exception e)
889 1023 tao
    {
890 2286 tao
891
      MetacatReplication.replErrorLog("Datafile " + docid +
892 1583 tao
                                      " failed to added to DB with " +
893
                                      "action " + dbaction + " because "+
894
                                       e.getMessage());
895 2663 sgarg
      logMetacat.error
896 1292 tao
              ("ERROR in MetacatReplication.handleForceDataFileReplicate" +
897 2663 sgarg
                         "Request(): " + e.getMessage());
898 1023 tao
    }
899
  }
900
  /**
901 561 berkley
   * Grants or denies a lock to a requesting host.
902
   * The servlet parameters of interrest are:
903
   * docid: the docid of the file the lock is being requested for
904
   * currentdate: the timestamp of the document on the remote server
905 2286 tao
   *
906 561 berkley
   */
907
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
908
                                    HttpServletResponse response)
909
  {
910 1292 tao
911 561 berkley
    try
912
    {
913 2286 tao
914 561 berkley
      String docid = ((String[])params.get("docid"))[0];
915 580 berkley
      String remoteRev = ((String[])params.get("updaterev"))[0];
916 1217 tao
      DocumentImpl requestDoc = new DocumentImpl(docid);
917 584 berkley
      MetacatReplication.replLog("lock request for " + docid);
918 580 berkley
      int localRevInt = requestDoc.getRev();
919
      int remoteRevInt = Integer.parseInt(remoteRev);
920 2286 tao
921 580 berkley
      if(remoteRevInt >= localRevInt)
922 561 berkley
      {
923
        if(!fileLocks.contains(docid))
924 580 berkley
        { //grant the lock if it is not already locked
925 561 berkley
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
926
          //send a message back to the the remote host authorizing the insert
927
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
928
          lockThread = new Thread(this);
929
          lockThread.setPriority(Thread.MIN_PRIORITY);
930
          lockThread.start();
931 584 berkley
          MetacatReplication.replLog("lock granted for " + docid);
932 561 berkley
        }
933
        else
934
        { //deny the lock
935
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
936 2286 tao
          MetacatReplication.replLog("lock denied for " + docid +
937 584 berkley
                                     "reason: file already locked");
938 561 berkley
        }
939
      }
940
      else
941
      {//deny the lock.
942
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
943 2286 tao
        MetacatReplication.replLog("lock denied for " + docid +
944 584 berkley
                                   "reason: client has outdated file");
945 561 berkley
      }
946 1217 tao
      //conn.close();
947 561 berkley
    }
948
    catch(Exception e)
949
    {
950 675 berkley
      System.out.println("error requesting file lock from MetacatReplication." +
951
                         "handleGetLockRequest: " + e.getMessage());
952 568 berkley
      e.printStackTrace(System.out);
953 561 berkley
    }
954
  }
955 2286 tao
956 561 berkley
  /**
957
   * Sends all of the xml_documents information encoded in xml to a requestor
958 583 berkley
   * the format is:
959
   * <!ELEMENT documentinfo (docid, docname, doctype, doctitle, user_owner,
960 1057 tao
   *                  user_updated, home_server, public_access, rev)/>
961 583 berkley
   * all of the subelements of document info are #PCDATA
962 561 berkley
   */
963 2286 tao
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params,
964 561 berkley
                                        HttpServletResponse response)
965
  {
966
    String docid = ((String[])(params.get("docid")))[0];
967
    StringBuffer sb = new StringBuffer();
968 2286 tao
969 561 berkley
    try
970
    {
971 2286 tao
972 1217 tao
      DocumentImpl doc = new DocumentImpl(docid);
973 561 berkley
      sb.append("<documentinfo><docid>").append(docid);
974
      sb.append("</docid><docname>").append(doc.getDocname());
975
      sb.append("</docname><doctype>").append(doc.getDoctype());
976 692 bojilova
      sb.append("</doctype>");
977
      sb.append("<user_owner>").append(doc.getUserowner());
978 561 berkley
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
979 1057 tao
      sb.append("</user_updated>");
980 2624 tao
      sb.append("<date_created>");
981
      sb.append(doc.getCreateDate());
982
      sb.append("</date_created>");
983
      sb.append("<date_updated>");
984
      sb.append(doc.getUpdateDate());
985
      sb.append("</date_updated>");
986 1057 tao
      sb.append("<home_server>");
987 1061 tao
      sb.append(doc.getDocHomeServer());
988 1057 tao
      sb.append("</home_server>");
989
      sb.append("<public_access>").append(doc.getPublicaccess());
990 583 berkley
      sb.append("</public_access><rev>").append(doc.getRev());
991 4419 leinfelder
      sb.append("</rev>");
992
993
      //permissions on the document
994
      PermissionController permController = new PermissionController(docid);
995
      Vector accessControlList = permController.getAccessControl();
996
      sb.append("<accessControl>");
997
      for (int i = 0; i < accessControlList.size(); i++) {
998
    	  AccessControlForSingleFile acfsf = (AccessControlForSingleFile) accessControlList.get(i);
999
    	  sb.append(acfsf.getAccessString());
1000
      }
1001
      sb.append("</accessControl>");
1002
1003
      sb.append("</documentinfo>");
1004 561 berkley
      response.setContentType("text/xml");
1005
      out.println(sb.toString());
1006 2286 tao
1007 561 berkley
    }
1008
    catch (Exception e)
1009
    {
1010 675 berkley
      System.out.println("error in " +
1011 2286 tao
                         "metacatReplication.handlegetdocumentinforequest: " +
1012 675 berkley
                          e.getMessage());
1013 561 berkley
    }
1014 2286 tao
1015 561 berkley
  }
1016 2286 tao
1017 1020 tao
  /**
1018
   * Sends a datafile to a remote host
1019
   */
1020 2286 tao
  private void handleGetDataFileRequest(OutputStream outPut,
1021 1020 tao
                            Hashtable params, HttpServletResponse response)
1022 2286 tao
1023 1020 tao
  {
1024 2286 tao
    // File path for data file
1025 4080 daigle
    String filepath;
1026 1292 tao
    // Request docid
1027 1020 tao
    String docId = ((String[])(params.get("docid")))[0];
1028 1023 tao
    //check if the doicd is null
1029
    if (docId==null)
1030
    {
1031 2663 sgarg
      logMetacat.error("Didn't specify docid for replication");
1032 1023 tao
      return;
1033
    }
1034 2286 tao
1035 1097 tao
    //try to open a https stream to test if the request server's public key
1036
    //in the key store, this is security issue
1037
    try
1038
    {
1039 4080 daigle
      filepath = PropertyService.getProperty("application.datafilepath");
1040 1097 tao
      String server = ((String[])params.get("server"))[0];
1041
      URL u = new URL("https://" + server + "?server="
1042 4080 daigle
                +MetaCatUtil.getLocalReplicationServerName()
1043 1097 tao
                +"&action=test");
1044
      String test = MetacatReplication.getURLContent(u);
1045
      //couldn't pass the test
1046
      if (test.indexOf("successfully")==-1)
1047
      {
1048
        //response.setContentType("text/xml");
1049
        //outPut.println("<error>Couldn't pass the trust test</error>");
1050 2663 sgarg
        logMetacat.error("Couldn't pass the trust test");
1051 1097 tao
        return;
1052
      }
1053
    }//try
1054
    catch (Exception ee)
1055
    {
1056
      return;
1057
    }//catch
1058 2286 tao
1059
    if(!filepath.endsWith("/"))
1060 1020 tao
    {
1061
          filepath += "/";
1062
    }
1063 1292 tao
    // Get file aboslute file name
1064 2286 tao
    String filename = filepath + docId;
1065
1066 1292 tao
    //MIME type
1067
    String contentType = null;
1068 2286 tao
    if (filename.endsWith(".xml"))
1069 1292 tao
    {
1070
        contentType="text/xml";
1071 2286 tao
    }
1072
    else if (filename.endsWith(".css"))
1073 1292 tao
    {
1074
        contentType="text/css";
1075 2286 tao
    }
1076
    else if (filename.endsWith(".dtd"))
1077 1292 tao
    {
1078
        contentType="text/plain";
1079 2286 tao
    }
1080
    else if (filename.endsWith(".xsd"))
1081 1292 tao
    {
1082
        contentType="text/xml";
1083 2286 tao
    }
1084
    else if (filename.endsWith("/"))
1085 1292 tao
    {
1086
        contentType="text/html";
1087 2286 tao
    }
1088
    else
1089 1292 tao
    {
1090
        File f = new File(filename);
1091 2286 tao
        if ( f.isDirectory() )
1092 1292 tao
        {
1093
           contentType="text/html";
1094 2286 tao
        }
1095 1292 tao
        else
1096
        {
1097
           contentType="application/octet-stream";
1098
        }
1099
     }
1100 2286 tao
1101 1292 tao
   // Set the mime type
1102 1020 tao
   response.setContentType(contentType);
1103 2286 tao
1104 1292 tao
   // Get the content of the file
1105 1020 tao
   FileInputStream fin = null;
1106 2286 tao
   try
1107 1020 tao
   {
1108 1292 tao
      // FileInputStream to metacat
1109 1020 tao
      fin = new FileInputStream(filename);
1110 1292 tao
      // 4K buffer
1111
      byte[] buf = new byte[4 * 1024];
1112
      // Read data from file input stream to byte array
1113 1020 tao
      int b = fin.read(buf);
1114 1292 tao
      // Write to outStream from byte array
1115 2286 tao
      while (b != -1)
1116 1020 tao
      {
1117
        outPut.write(buf, 0, b);
1118
        b = fin.read(buf);
1119
      }
1120 1292 tao
      // close file input stream
1121 1020 tao
      fin.close();
1122 2286 tao
1123 1292 tao
   }//try
1124 1020 tao
   catch(Exception e)
1125
   {
1126
      System.out.println("error getting data file from MetacatReplication." +
1127
                         "handlGetDataFileRequest " + e.getMessage());
1128
      e.printStackTrace(System.out);
1129 1292 tao
   }//catch
1130 2286 tao
1131 1020 tao
}
1132 2286 tao
1133
1134 561 berkley
  /**
1135
   * Sends a document to a remote host
1136
   */
1137 2286 tao
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params,
1138 561 berkley
                                        HttpServletResponse response)
1139 534 berkley
  {
1140 2286 tao
1141 534 berkley
    try
1142
    {
1143 1097 tao
      //try to open a https stream to test if the request server's public key
1144
      //in the key store, this is security issue
1145
      String server = ((String[])params.get("server"))[0];
1146
      URL u = new URL("https://" + server + "?server="
1147 4080 daigle
                +MetaCatUtil.getLocalReplicationServerName()
1148 1097 tao
                +"&action=test");
1149
      String test = MetacatReplication.getURLContent(u);
1150
      //couldn't pass the test
1151
      if (test.indexOf("successfully")==-1)
1152
      {
1153
        response.setContentType("text/xml");
1154 2717 tao
        out.println("<error>Couldn't pass the trust test "+test+" </error>");
1155 1292 tao
        out.close();
1156 1097 tao
        return;
1157
      }
1158 2286 tao
1159 536 berkley
      String docid = ((String[])(params.get("docid")))[0];
1160 2286 tao
1161 1217 tao
      DocumentImpl di = new DocumentImpl(docid);
1162 534 berkley
      response.setContentType("text/xml");
1163 1767 tao
      out.print(di.toString(null, null, true));
1164 2286 tao
1165 584 berkley
      MetacatReplication.replLog("document " + docid + " sent");
1166 2286 tao
1167 534 berkley
    }
1168
    catch(Exception e)
1169
    {
1170 2663 sgarg
      logMetacat.error("error getting document from MetacatReplication."
1171
                          +"handlGetDocumentRequest " + e.getMessage());
1172 1099 tao
      //e.printStackTrace(System.out);
1173
      response.setContentType("text/xml");
1174 1292 tao
      out.println("<error>"+e.getMessage()+"</error>");
1175 534 berkley
    }
1176 2286 tao
1177 534 berkley
  }
1178 2286 tao
1179 573 berkley
  /**
1180 583 berkley
   * Sends a list of all of the documents on this sever along with their
1181 2286 tao
   * revision numbers.
1182 583 berkley
   * The format is:
1183
   * <!ELEMENT replication (server, updates)>
1184
   * <!ELEMENT server (#PCDATA)>
1185 2597 tao
   * <!ELEMENT updates ((updatedDocument | deleteDocument | revisionDocument)*)>
1186 1020 tao
   * <!ELEMENT updatedDocument (docid, rev, datafile*)>
1187 1035 tao
   * <!ELEMENT deletedDocument (docid, rev)>
1188 2597 tao
   * <!ELEMENT revisionDocument (docid, rev, datafile*)>
1189 583 berkley
   * <!ELEMENT docid (#PCDATA)>
1190
   * <!ELEMENT rev (#PCDATA)>
1191 1020 tao
   * <!ELEMENT datafile (#PCDATA)>
1192 583 berkley
   * note that the rev in deletedDocument is always empty.  I just left
1193
   * it in there to make the parser implementation easier.
1194 573 berkley
   */
1195 2286 tao
  private void handleUpdateRequest(PrintWriter out, Hashtable params,
1196 577 berkley
                                    HttpServletResponse response)
1197
  {
1198 2286 tao
    // Checked out DBConnection
1199 1217 tao
    DBConnection dbConn = null;
1200 1292 tao
    // DBConenction serial number when checked it out
1201 1217 tao
    int serialNumber = -1;
1202
    PreparedStatement pstmt = null;
1203 1292 tao
    // Server list to store server info of xml_replication table
1204
    ReplicationServerList serverList = null;
1205 2286 tao
1206 577 berkley
    try
1207
    {
1208 1292 tao
      // Check out a DBConnection from pool
1209
      dbConn=DBConnectionPool.
1210
                  getDBConnection("MetacatReplication.handleUpdateRequest");
1211
      serialNumber=dbConn.getCheckOutSerialNumber();
1212
      // Create a server list from xml_replication table
1213
      serverList = new ReplicationServerList();
1214 2286 tao
1215 1292 tao
      // Get remote server name from param
1216
      String server = ((String[])params.get("server"))[0];
1217
      // If no servr name in param, return a error
1218
      if ( server == null || server.equals(""))
1219
      {
1220
        response.setContentType("text/xml");
1221
        out.println("<error>Request didn't specify server name</error>");
1222
        out.close();
1223
        return;
1224
      }//if
1225 2286 tao
1226 1101 tao
      //try to open a https stream to test if the request server's public key
1227
      //in the key store, this is security issue
1228
      URL u = new URL("https://" + server + "?server="
1229 4080 daigle
                +MetaCatUtil.getLocalReplicationServerName()
1230 1101 tao
                +"&action=test");
1231
      String test = MetacatReplication.getURLContent(u);
1232
      //couldn't pass the test
1233
      if (test.indexOf("successfully")==-1)
1234
      {
1235
        response.setContentType("text/xml");
1236
        out.println("<error>Couldn't pass the trust test</error>");
1237 1292 tao
        out.close();
1238 1101 tao
        return;
1239
      }
1240 2286 tao
1241
1242 1292 tao
      // Check if local host configure to replicate xml documents to remote
1243
      // server. If not send back a error message
1244
      if (!serverList.getReplicationValue(server))
1245
      {
1246
        response.setContentType("text/xml");
1247
        out.println
1248
        ("<error>Configuration not allow to replicate document to you</error>");
1249
        out.close();
1250
        return;
1251
      }//if
1252 2286 tao
1253 1292 tao
      // Store the sql command
1254 577 berkley
      StringBuffer docsql = new StringBuffer();
1255 2597 tao
      StringBuffer revisionSql = new StringBuffer();
1256 1292 tao
      // Stroe the docid list
1257 577 berkley
      StringBuffer doclist = new StringBuffer();
1258 1292 tao
      // Store the deleted docid list
1259
      StringBuffer delsql = new StringBuffer();
1260
      // Store the data set file
1261 625 berkley
      Vector packageFiles = new Vector();
1262 2286 tao
1263 1292 tao
      // Append local server's name and replication servlet to doclist
1264 577 berkley
      doclist.append("<?xml version=\"1.0\"?><replication>");
1265 4080 daigle
      doclist.append("<server>").append(MetaCatUtil.getLocalReplicationServerName());
1266
      //doclist.append(util.getProperty("replicationpath"));
1267 577 berkley
      doclist.append("</server><updates>");
1268 2286 tao
1269 1292 tao
      // Get correct docid that reside on this server according the requesting
1270
      // server's replicate and data replicate value in xml_replication table
1271 4335 daigle
      docsql.append(DatabaseService.getDBAdapter().getReplicationDocumentListSQL());
1272 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)) ");
1273 2597 tao
      revisionSql.append("select docid, rev, doctype from xml_revisions ");
1274 1292 tao
      // If the localhost is not a hub to the remote server, only replicate
1275
      // the docid' which home server is local host (server_location =1)
1276
      if (!serverList.getHubValue(server))
1277 1042 tao
      {
1278 2724 tao
    	String serverLocationDoc = " and a.server_location = 1";
1279 2719 tao
        String serverLocationRev = "where server_location = 1";
1280
        docsql.append(serverLocationDoc);
1281
        revisionSql.append(serverLocationRev);
1282 1042 tao
      }
1283 2663 sgarg
      logMetacat.info("Doc sql: "+docsql.toString());
1284 2286 tao
1285 1292 tao
      // Get any deleted documents
1286 577 berkley
      delsql.append("select distinct docid from ");
1287
      delsql.append("xml_revisions where docid not in (select docid from ");
1288 1042 tao
      delsql.append("xml_documents) ");
1289 1292 tao
      // If the localhost is not a hub to the remote server, only replicate
1290
      // the docid' which home server is local host (server_location =1)
1291
      if (!serverList.getHubValue(server))
1292 1042 tao
      {
1293
        delsql.append("and server_location = 1");
1294
      }
1295 2663 sgarg
      logMetacat.info("Deleted sql: "+delsql.toString());
1296 2286 tao
1297
1298
1299 1292 tao
      // Get docid list of local host
1300 1217 tao
      pstmt = dbConn.prepareStatement(docsql.toString());
1301 577 berkley
      pstmt.execute();
1302
      ResultSet rs = pstmt.getResultSet();
1303
      boolean tablehasrows = rs.next();
1304 1035 tao
      //If metacat configed to replicate data file
1305 4080 daigle
      //if ((util.getProperty("replicationsenddata")).equals("on"))
1306 2597 tao
      boolean replicateData = serverList.getDataReplicationValue(server);
1307
      if (replicateData)
1308 577 berkley
      {
1309 1020 tao
        while(tablehasrows)
1310
        {
1311
          String recordDoctype = rs.getString(3);
1312 1035 tao
          Vector packagedoctypes = MetaCatUtil.getOptionList(
1313 4213 daigle
                                     PropertyService.getProperty("xml.packagedoctype"));
1314 1292 tao
          //if this is a package file, put it at the end
1315
          //because if a package file is read before all of the files it
1316
          //refers to are loaded then there is an error
1317 1768 tao
          if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1318 2286 tao
          {
1319 1292 tao
              //If this is not data file
1320 1035 tao
              if (!recordDoctype.equals("BIN"))
1321
              {
1322
                //for non-data file document
1323
                doclist.append("<updatedDocument>");
1324
                doclist.append("<docid>").append(rs.getString(1));
1325
                doclist.append("</docid><rev>").append(rs.getInt(2));
1326
                doclist.append("</rev>");
1327
                doclist.append("</updatedDocument>");
1328 1292 tao
              }//if
1329 1035 tao
              else
1330
              {
1331
                //for data file document, in datafile attributes
1332
                //we put "datafile" value there
1333
                doclist.append("<updatedDocument>");
1334
                doclist.append("<docid>").append(rs.getString(1));
1335
                doclist.append("</docid><rev>").append(rs.getInt(2));
1336
                doclist.append("</rev>");
1337
                doclist.append("<datafile>");
1338 4173 daigle
                doclist.append(PropertyService.getProperty("replication.datafileflag"));
1339 1035 tao
                doclist.append("</datafile>");
1340
                doclist.append("</updatedDocument>");
1341 2286 tao
              }//else
1342 1292 tao
          }//if packagedoctpes
1343 1035 tao
          else
1344
          { //the package files are saved to be put into the xml later.
1345
              Vector v = new Vector();
1346
              v.add(new String(rs.getString(1)));
1347
              v.add(new Integer(rs.getInt(2)));
1348
              packageFiles.add(new Vector(v));
1349 1292 tao
          }//esle
1350 1035 tao
          tablehasrows = rs.next();
1351
        }//while
1352
      }//if
1353
      else //metacat was configured not to send data file
1354
      {
1355
        while(tablehasrows)
1356
        {
1357
          String recordDoctype = rs.getString(3);
1358 2286 tao
          if(!recordDoctype.equals("BIN"))
1359 1020 tao
          { //don't replicate data files
1360
            Vector packagedoctypes = MetaCatUtil.getOptionList(
1361 4213 daigle
                                     PropertyService.getProperty("xml.packagedoctype"));
1362 1768 tao
            if(recordDoctype != null && !packagedoctypes.contains(recordDoctype))
1363 1020 tao
            {   //if this is a package file, put it at the end
1364
              //because if a package file is read before all of the files it
1365
              //refers to are loaded then there is an error
1366
              doclist.append("<updatedDocument>");
1367
              doclist.append("<docid>").append(rs.getString(1));
1368
              doclist.append("</docid><rev>").append(rs.getInt(2));
1369
              doclist.append("</rev>");
1370
              doclist.append("</updatedDocument>");
1371
            }
1372
            else
1373
            { //the package files are saved to be put into the xml later.
1374
              Vector v = new Vector();
1375
              v.add(new String(rs.getString(1)));
1376
              v.add(new Integer(rs.getInt(2)));
1377
              packageFiles.add(new Vector(v));
1378
            }
1379
         }//if
1380
         tablehasrows = rs.next();
1381
        }//while
1382 1035 tao
      }//else
1383 2286 tao
1384 1217 tao
      pstmt = dbConn.prepareStatement(delsql.toString());
1385
      //usage count should increas 1
1386
      dbConn.increaseUsageCount(1);
1387 2286 tao
1388 577 berkley
      pstmt.execute();
1389
      rs = pstmt.getResultSet();
1390
      tablehasrows = rs.next();
1391
      while(tablehasrows)
1392
      { //handle the deleted documents
1393
        doclist.append("<deletedDocument><docid>").append(rs.getString(1));
1394
        doclist.append("</docid><rev></rev></deletedDocument>");
1395 583 berkley
        //note that rev is always empty for deleted docs
1396 577 berkley
        tablehasrows = rs.next();
1397
      }
1398 2286 tao
1399 625 berkley
      //now we can put the package files into the xml results
1400
      for(int i=0; i<packageFiles.size(); i++)
1401
      {
1402
        Vector v = (Vector)packageFiles.elementAt(i);
1403
        doclist.append("<updatedDocument>");
1404
        doclist.append("<docid>").append((String)v.elementAt(0));
1405
        doclist.append("</docid><rev>");
1406
        doclist.append(((Integer)v.elementAt(1)).intValue());
1407
        doclist.append("</rev>");
1408
        doclist.append("</updatedDocument>");
1409
      }
1410 2597 tao
      // add revision doc list
1411
      doclist.append(prepareRevisionDoc(dbConn,revisionSql.toString(),replicateData));
1412
1413 577 berkley
      doclist.append("</updates></replication>");
1414 2663 sgarg
      logMetacat.info("doclist: " + doclist.toString());
1415 667 berkley
      pstmt.close();
1416 1217 tao
      //conn.close();
1417 577 berkley
      response.setContentType("text/xml");
1418
      out.println(doclist.toString());
1419 2286 tao
1420 577 berkley
    }
1421
    catch(Exception e)
1422
    {
1423 2663 sgarg
      logMetacat.error("error in MetacatReplication." +
1424
                         "handleupdaterequest: " + e.getMessage());
1425 1101 tao
      //e.printStackTrace(System.out);
1426
      response.setContentType("text/xml");
1427 1292 tao
      out.println("<error>"+e.getMessage()+"</error>");
1428 577 berkley
    }
1429 1217 tao
    finally
1430
    {
1431
      try
1432
      {
1433
        pstmt.close();
1434
      }//try
1435
      catch (SQLException ee)
1436
      {
1437 2663 sgarg
        logMetacat.error("Error in MetacatReplication." +
1438
                "handleUpdaterequest to close pstmt: "+ee.getMessage());
1439 1217 tao
      }//catch
1440
      finally
1441
      {
1442
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1443
      }//finally
1444
    }//finally
1445 2286 tao
1446 1292 tao
  }//handlUpdateRequest
1447 2597 tao
1448
  /*
1449
   * This method will get the xml string for document in xml_revision
1450
   * The schema look like <!ELEMENT revisionDocument (docid, rev, datafile*)>
1451
   */
1452
  private String prepareRevisionDoc(DBConnection dbConn, String revSql,
1453
                            boolean replicateData) throws Exception
1454
  {
1455 2663 sgarg
      logMetacat.warn("The revision document sql is "+ revSql);
1456 2597 tao
      StringBuffer revDocList = new StringBuffer();
1457 2619 tao
      PreparedStatement pstmt = dbConn.prepareStatement(revSql);
1458 2597 tao
      //usage count should increas 1
1459
      dbConn.increaseUsageCount(1);
1460 2286 tao
1461 2597 tao
      pstmt.execute();
1462
      ResultSet rs = pstmt.getResultSet();
1463
      boolean tablehasrows = rs.next();
1464
      while(tablehasrows)
1465
      {
1466
        String recordDoctype = rs.getString(3);
1467
1468
        //If this is data file and it isn't configured to replicate data
1469
        if (recordDoctype.equals("BIN") && !replicateData)
1470
        {
1471
            // do nothing
1472
            continue;
1473
        }
1474
        else
1475
        {
1476
1477
            revDocList.append("<revisionDocument>");
1478
            revDocList.append("<docid>").append(rs.getString(1));
1479
            revDocList.append("</docid><rev>").append(rs.getInt(2));
1480
            revDocList.append("</rev>");
1481
            // data file
1482
            if (recordDoctype.equals("BIN"))
1483
            {
1484
                revDocList.append("<datafile>");
1485 4173 daigle
                revDocList.append(PropertyService.getProperty("replication.datafileflag"));
1486 2597 tao
                revDocList.append("</datafile>");
1487
            }
1488 2619 tao
            revDocList.append("</revisionDocument>");
1489 2597 tao
1490
         }//else
1491 2619 tao
         tablehasrows = rs.next();
1492 2597 tao
      }
1493 2619 tao
      //System.out.println("The revision list is"+ revDocList.toString());
1494 2597 tao
      return revDocList.toString();
1495
  }
1496
1497 577 berkley
  /**
1498 590 berkley
   * Returns the xml_catalog table encoded in xml
1499
   */
1500
  public static String getCatalogXML()
1501
  {
1502
    return handleGetCatalogRequest(null, null, null, false);
1503
  }
1504 2286 tao
1505 590 berkley
  /**
1506
   * Sends the contents of the xml_catalog table encoded in xml
1507
   * The xml format is:
1508
   * <!ELEMENT xml_catalog (row*)>
1509
   * <!ELEMENT row (entry_type, source_doctype, target_doctype, public_id,
1510
   *                system_id)>
1511
   * All of the sub elements of row are #PCDATA
1512 2286 tao
1513 590 berkley
   * If printFlag == false then do not print to out.
1514
   */
1515 2286 tao
  private static String handleGetCatalogRequest(PrintWriter out,
1516 590 berkley
                                                Hashtable params,
1517
                                                HttpServletResponse response,
1518
                                                boolean printFlag)
1519
  {
1520 1217 tao
    DBConnection dbConn = null;
1521
    int serialNumber = -1;
1522 667 berkley
    PreparedStatement pstmt = null;
1523 590 berkley
    try
1524 2286 tao
    {
1525 1217 tao
      /*conn = MetacatReplication.getDBConnection("MetacatReplication." +
1526
                                                "handleGetCatalogRequest");*/
1527
      dbConn=DBConnectionPool.
1528
                 getDBConnection("MetacatReplication.handleGetCatalogRequest");
1529
      serialNumber=dbConn.getCheckOutSerialNumber();
1530
      pstmt = dbConn.prepareStatement("select entry_type, " +
1531 590 berkley
                              "source_doctype, target_doctype, public_id, " +
1532
                              "system_id from xml_catalog");
1533
      pstmt.execute();
1534
      ResultSet rs = pstmt.getResultSet();
1535
      boolean tablehasrows = rs.next();
1536
      StringBuffer sb = new StringBuffer();
1537
      sb.append("<?xml version=\"1.0\"?><xml_catalog>");
1538
      while(tablehasrows)
1539
      {
1540
        sb.append("<row><entry_type>").append(rs.getString(1));
1541
        sb.append("</entry_type><source_doctype>").append(rs.getString(2));
1542
        sb.append("</source_doctype><target_doctype>").append(rs.getString(3));
1543
        sb.append("</target_doctype><public_id>").append(rs.getString(4));
1544 4080 daigle
        // system id may not have server url on front.  Add it if not.
1545
        String systemID = rs.getString(5);
1546
        if (!systemID.startsWith("http://")) {
1547 4123 daigle
        	systemID = SystemUtil.getContextURL() + systemID;
1548 4080 daigle
        }
1549
        sb.append("</public_id><system_id>").append(systemID);
1550 590 berkley
        sb.append("</system_id></row>");
1551 2286 tao
1552 590 berkley
        tablehasrows = rs.next();
1553
      }
1554
      sb.append("</xml_catalog>");
1555 1217 tao
      //conn.close();
1556 590 berkley
      if(printFlag)
1557
      {
1558
        response.setContentType("text/xml");
1559
        out.println(sb.toString());
1560
      }
1561 667 berkley
      pstmt.close();
1562 590 berkley
      return sb.toString();
1563
    }
1564
    catch(Exception e)
1565
    {
1566 2286 tao
1567 2663 sgarg
      logMetacat.error("error in MetacatReplication.handleGetCatalogRequest:"+
1568
                          e.getMessage());
1569 590 berkley
      e.printStackTrace(System.out);
1570 1292 tao
      if(printFlag)
1571
      {
1572
        out.println("<error>"+e.getMessage()+"</error>");
1573
      }
1574 590 berkley
    }
1575 1217 tao
    finally
1576
    {
1577
      try
1578
      {
1579
        pstmt.close();
1580
      }//try
1581
      catch (SQLException ee)
1582
      {
1583 2663 sgarg
        logMetacat.error("Error in MetacatReplication.handleGetCatalogRequest: "
1584
           +ee.getMessage());
1585 1217 tao
      }//catch
1586
      finally
1587
      {
1588
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1589
      }//finally
1590
    }//finally
1591 2286 tao
1592 590 berkley
    return null;
1593
  }
1594 2286 tao
1595 590 berkley
  /**
1596 568 berkley
   * Sends the current system date to the remote server.  Using this action
1597 2286 tao
   * for replication gets rid of any problems with syncronizing clocks
1598 568 berkley
   * because a time specific to a document is always kept on its home server.
1599
   */
1600 2286 tao
  private void handleGetTimeRequest(PrintWriter out, Hashtable params,
1601 568 berkley
                                    HttpServletResponse response)
1602
  {
1603 1752 tao
    SimpleDateFormat formatter = new SimpleDateFormat ("MM/dd/yy HH:mm:ss");
1604 568 berkley
    java.util.Date localtime = new java.util.Date();
1605
    String dateString = formatter.format(localtime);
1606
    response.setContentType("text/xml");
1607 2286 tao
1608 568 berkley
    out.println("<timestamp>" + dateString + "</timestamp>");
1609
  }
1610 2286 tao
1611 568 berkley
  /**
1612 2286 tao
   * this method handles the timeout for a file lock.  when a lock is
1613 583 berkley
   * granted it is granted for 30 seconds.  When this thread runs out
1614
   * it deletes the docid from the queue, thus eliminating the lock.
1615 561 berkley
   */
1616
  public void run()
1617
  {
1618
    try
1619
    {
1620 2663 sgarg
      logMetacat.info("thread started for docid: " +
1621
                               (String)fileLocks.elementAt(0));
1622 2286 tao
1623 561 berkley
      Thread.sleep(30000); //the lock will expire in 30 seconds
1624 2663 sgarg
      logMetacat.info("thread for docid: " +
1625 2286 tao
                             (String)fileLocks.elementAt(fileLocks.size() - 1) +
1626 2663 sgarg
                              " exiting.");
1627 2286 tao
1628 561 berkley
      fileLocks.remove(fileLocks.size() - 1);
1629 568 berkley
      //fileLocks is treated as a FIFO queue.  If there are more than one lock
1630 561 berkley
      //in the vector, the first one inserted will be removed.
1631
    }
1632
    catch(Exception e)
1633
    {
1634 2663 sgarg
      logMetacat.error("error in file lock thread from " +
1635
                                "MetacatReplication.run: " + e.getMessage());
1636 561 berkley
    }
1637
  }
1638 2286 tao
1639 561 berkley
  /**
1640
   * Returns the name of a server given a serverCode
1641
   * @param serverCode the serverid of the server
1642
   * @return the servername or null if the specified serverCode does not
1643
   *         exist.
1644
   */
1645 1292 tao
  public static String getServerNameForServerCode(int serverCode)
1646 561 berkley
  {
1647 569 berkley
    //System.out.println("serverid: " + serverCode);
1648 1217 tao
    DBConnection dbConn = null;
1649
    int serialNumber = -1;
1650
    PreparedStatement pstmt = null;
1651 561 berkley
    try
1652
    {
1653 1217 tao
      dbConn=DBConnectionPool.
1654
                  getDBConnection("MetacatReplication.getServer");
1655
      serialNumber=dbConn.getCheckOutSerialNumber();
1656 569 berkley
      String sql = new String("select server from " +
1657 2286 tao
                              "xml_replication where serverid = " +
1658 561 berkley
                              serverCode);
1659 1217 tao
      pstmt = dbConn.prepareStatement(sql);
1660 569 berkley
      //System.out.println("getserver sql: " + sql);
1661 561 berkley
      pstmt.execute();
1662
      ResultSet rs = pstmt.getResultSet();
1663
      boolean tablehasrows = rs.next();
1664
      if(tablehasrows)
1665
      {
1666 569 berkley
        //System.out.println("server: " + rs.getString(1));
1667 561 berkley
        return rs.getString(1);
1668
      }
1669 2286 tao
1670 1217 tao
      //conn.close();
1671 561 berkley
    }
1672
    catch(Exception e)
1673
    {
1674 2286 tao
      System.out.println("Error in MetacatReplication.getServer: " +
1675 561 berkley
                          e.getMessage());
1676
    }
1677 1217 tao
    finally
1678
    {
1679
      try
1680
      {
1681
        pstmt.close();
1682
      }//try
1683
      catch (SQLException ee)
1684
      {
1685 2663 sgarg
        logMetacat.error("Error in MetacactReplication.getserver: "+
1686
                                    ee.getMessage());
1687 1217 tao
      }//catch
1688
      finally
1689
      {
1690
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1691
      }//fianlly
1692
    }//finally
1693 2286 tao
1694
1695
1696 561 berkley
    return null;
1697
      //return null if the server does not exist
1698
  }
1699 2286 tao
1700 569 berkley
  /**
1701
   * Returns a server code given a server name
1702
   * @param server the name of the server
1703
   * @return integer > 0 representing the code of the server, 0 if the server
1704
   *  does not exist.
1705
   */
1706 1292 tao
  public static int getServerCodeForServerName(String server) throws Exception
1707 569 berkley
  {
1708 1217 tao
    DBConnection dbConn = null;
1709
    int serialNumber = -1;
1710 667 berkley
    PreparedStatement pstmt = null;
1711 837 bojilova
    int serverCode = 0;
1712
1713
    try {
1714
1715 1217 tao
      //conn = util.openDBConnection();
1716
      dbConn=DBConnectionPool.
1717
                  getDBConnection("MetacatReplication.getServerCode");
1718
      serialNumber=dbConn.getCheckOutSerialNumber();
1719
      pstmt = dbConn.prepareStatement("SELECT serverid FROM xml_replication " +
1720 837 bojilova
                                    "WHERE server LIKE '" + server + "'");
1721 569 berkley
      pstmt.execute();
1722
      ResultSet rs = pstmt.getResultSet();
1723
      boolean tablehasrows = rs.next();
1724 2286 tao
      if ( tablehasrows ) {
1725 837 bojilova
        serverCode = rs.getInt(1);
1726 667 berkley
        pstmt.close();
1727 1217 tao
        //conn.close();
1728 837 bojilova
        return serverCode;
1729 569 berkley
      }
1730 2286 tao
1731 837 bojilova
    } catch(Exception e) {
1732
      throw e;
1733
1734
    } finally {
1735 2286 tao
      try
1736 1217 tao
      {
1737 667 berkley
        pstmt.close();
1738 1217 tao
        //conn.close();
1739
       }//try
1740 2286 tao
       catch(Exception ee)
1741 1217 tao
       {
1742 2663 sgarg
         logMetacat.error("Error in MetacatReplicatio.getServerCode: "
1743
                                  +ee.getMessage());
1744 2286 tao
1745 1217 tao
       }//catch
1746
       finally
1747
       {
1748
         DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1749
       }//finally
1750
    }//finally
1751 2286 tao
1752 837 bojilova
    return serverCode;
1753 569 berkley
  }
1754 2286 tao
1755 569 berkley
  /**
1756 1292 tao
   * Method to get a host server information for given docid
1757
   * @param conn a connection to the database
1758
   */
1759
  public static Hashtable getHomeServerInfoForDocId(String docId)
1760
  {
1761
    Hashtable sl = new Hashtable();
1762
    DBConnection dbConn = null;
1763
    int serialNumber = -1;
1764
    docId=MetaCatUtil.getDocIdFromString(docId);
1765
    PreparedStatement pstmt=null;
1766
    int serverLocation;
1767
    try
1768
    {
1769
      //get conection
1770
      dbConn=DBConnectionPool.
1771
                  getDBConnection("ReplicationHandler.getHomeServer");
1772
      serialNumber=dbConn.getCheckOutSerialNumber();
1773
      //get a server location from xml_document table
1774
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
1775
                                            +"where docid = ?");
1776
      pstmt.setString(1, docId);
1777
      pstmt.execute();
1778
      ResultSet serverName = pstmt.getResultSet();
1779
      //get a server location
1780
      if(serverName.next())
1781
      {
1782
        serverLocation=serverName.getInt(1);
1783
        pstmt.close();
1784
      }
1785
      else
1786
      {
1787
        pstmt.close();
1788
        //ut.returnConnection(conn);
1789
        return null;
1790
      }
1791
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
1792
                        "from xml_replication where serverid = ?");
1793
      //increase usage count
1794
      dbConn.increaseUsageCount(1);
1795
      pstmt.setInt(1, serverLocation);
1796
      pstmt.execute();
1797
      ResultSet rs = pstmt.getResultSet();
1798
      boolean tableHasRows = rs.next();
1799
      if (tableHasRows)
1800
      {
1801 2286 tao
1802 1292 tao
          String server = rs.getString(1);
1803
          String last_checked = rs.getString(2);
1804
          if(!server.equals("localhost"))
1805
          {
1806
            sl.put(server, last_checked);
1807
          }
1808 2286 tao
1809 1292 tao
      }
1810
      else
1811
      {
1812
        pstmt.close();
1813
        //ut.returnConnection(conn);
1814
        return null;
1815
      }
1816
      pstmt.close();
1817
    }
1818
    catch(Exception e)
1819
    {
1820
      System.out.println("error in replicationHandler.getHomeServer(): " +
1821
                         e.getMessage());
1822
    }
1823
    finally
1824
    {
1825
      try
1826
      {
1827
        pstmt.close();
1828
        //ut.returnConnection(conn);
1829
      }
1830
      catch (Exception ee)
1831
      {
1832 2663 sgarg
        logMetacat.error("Eror irn rplicationHandler.getHomeServer() "+
1833
                          "to close pstmt: "+ee.getMessage());
1834 1292 tao
      }
1835
      finally
1836
      {
1837
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1838
      }
1839 2286 tao
1840 1292 tao
    }//finally
1841
    return sl;
1842
  }
1843 2286 tao
1844 1292 tao
  /**
1845
   * Returns a home server location  given a accnum
1846
   * @param accNum , given accNum for a document
1847 2286 tao
   *
1848 1292 tao
   */
1849
  public static int getHomeServerCodeForDocId(String accNum) throws Exception
1850
  {
1851
    DBConnection dbConn = null;
1852
    int serialNumber = -1;
1853
    PreparedStatement pstmt = null;
1854
    int serverCode = 1;
1855
    String docId=MetaCatUtil.getDocIdFromString(accNum);
1856
1857 2286 tao
    try
1858 1292 tao
    {
1859
1860
      // Get DBConnection
1861
      dbConn=DBConnectionPool.
1862
                  getDBConnection("ReplicationHandler.getServerLocation");
1863
      serialNumber=dbConn.getCheckOutSerialNumber();
1864 2286 tao
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
1865 1292 tao
                              + "WHERE docid LIKE '" + docId + "'");
1866
      pstmt.execute();
1867
      ResultSet rs = pstmt.getResultSet();
1868
      boolean tablehasrows = rs.next();
1869
      //If a document is find, return the server location for it
1870 2286 tao
      if ( tablehasrows )
1871
      {
1872 1292 tao
        serverCode = rs.getInt(1);
1873
        pstmt.close();
1874
        //conn.close();
1875
        return serverCode;
1876
      }
1877
      //if couldn't find in xml_documents table, we think server code is 1
1878
      //(this is new document)
1879
      else
1880
      {
1881
        pstmt.close();
1882
        //conn.close();
1883
        return serverCode;
1884
      }
1885 2286 tao
1886
    }
1887
    catch(Exception e)
1888 1292 tao
    {
1889 2286 tao
1890 1292 tao
      throw e;
1891
1892 2286 tao
    }
1893
    finally
1894 1292 tao
    {
1895 2286 tao
      try
1896 1292 tao
      {
1897
        pstmt.close();
1898
        //conn.close();
1899 2286 tao
1900
      }
1901
      catch(Exception ee)
1902 1292 tao
      {
1903 2663 sgarg
        logMetacat.error("Erorr in Replication.getServerLocation "+
1904
                     "to close pstmt"+ee.getMessage());
1905 1292 tao
      }
1906
      finally
1907
      {
1908
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1909
      }//finally
1910
    }//finally
1911
   //return serverCode;
1912
  }
1913 2286 tao
1914
1915
1916 1292 tao
  /**
1917 569 berkley
   * This method returns the content of a url
1918
   * @param u the url to return the content from
1919
   * @return a string representing the content of the url
1920
   * @throws java.io.IOException
1921
   */
1922
  public static String getURLContent(URL u) throws java.io.IOException
1923
  {
1924
    char istreamChar;
1925
    int istreamInt;
1926 2663 sgarg
    logMetacat.info("Before open the stream"+u.toString());
1927 1606 tao
    InputStream input = u.openStream();
1928 2663 sgarg
    logMetacat.info("Afetr open the stream"+u.toString());
1929 1606 tao
    InputStreamReader istream = new InputStreamReader(input);
1930 569 berkley
    StringBuffer serverResponse = new StringBuffer();
1931
    while((istreamInt = istream.read()) != -1)
1932
    {
1933
      istreamChar = (char)istreamInt;
1934
      serverResponse.append(istreamChar);
1935
    }
1936 1606 tao
    istream.close();
1937
    input.close();
1938 2286 tao
1939 569 berkley
    return serverResponse.toString();
1940
  }
1941 2286 tao
1942 584 berkley
  /**
1943 4080 daigle
	 * Method for writing replication messages to a log file specified in
1944
	 * metacat.properties
1945
	 */
1946
	public static void replLog(String message) {
1947
		try {
1948
			FileOutputStream fos =
1949 4173 daigle
				new FileOutputStream(PropertyService.getProperty("replication.logdir")
1950
					+ "/metacatreplication.log", true);
1951 4080 daigle
			PrintWriter pw = new PrintWriter(fos);
1952
			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
1953
			java.util.Date localtime = new java.util.Date();
1954
			String dateString = formatter.format(localtime);
1955
			dateString += " :: " + message;
1956
			// time stamp each entry
1957
			pw.println(dateString);
1958
			pw.flush();
1959
		} catch (Exception e) {
1960
			System.out.println("error writing to replication log from "
1961
					+ "MetacatReplication.replLog: " + e.getMessage());
1962
			// e.printStackTrace(System.out);
1963
		}
1964
	}
1965 2286 tao
1966 629 berkley
  /**
1967 4080 daigle
	 * Method for writing replication messages to a log file specified in
1968
	 * metacat.properties
1969
	 */
1970 1583 tao
  public static void replErrorLog(String message)
1971
  {
1972
    try
1973
    {
1974 4420 leinfelder
    	FileOutputStream fos =
1975
			new FileOutputStream(PropertyService.getProperty("replication.logdir")
1976
				+ "/metacatreplicationerror.log", true);
1977 1583 tao
      PrintWriter pw = new PrintWriter(fos);
1978
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
1979
      java.util.Date localtime = new java.util.Date();
1980
      String dateString = formatter.format(localtime);
1981
      dateString += " :: " + message;
1982
      //time stamp each entry
1983
      pw.println(dateString);
1984
      pw.flush();
1985
    }
1986
    catch(Exception e)
1987
    {
1988 4420 leinfelder
      System.out.println("error writing to replication error log from " +
1989
                         "MetacatReplication.replErrorLog: " + e.getMessage());
1990 1583 tao
      //e.printStackTrace(System.out);
1991
    }
1992
  }
1993 2286 tao
1994 1583 tao
  /**
1995 629 berkley
   * Returns true if the replicate field for server in xml_replication is 1.
1996
   * Returns false otherwise
1997
   */
1998
  public static boolean replToServer(String server)
1999
  {
2000 1217 tao
    DBConnection dbConn = null;
2001
    int serialNumber = -1;
2002 667 berkley
    PreparedStatement pstmt = null;
2003 629 berkley
    try
2004
    {
2005 1217 tao
      dbConn=DBConnectionPool.
2006
                  getDBConnection("MetacatReplication.repltoServer");
2007
      serialNumber=dbConn.getCheckOutSerialNumber();
2008 2286 tao
      pstmt = dbConn.prepareStatement("select replicate from " +
2009 667 berkley
                                    "xml_replication where server like '" +
2010
                                     server + "'");
2011 629 berkley
      pstmt.execute();
2012
      ResultSet rs = pstmt.getResultSet();
2013
      boolean tablehasrows = rs.next();
2014
      if(tablehasrows)
2015
      {
2016
        int i = rs.getInt(1);
2017
        if(i == 1)
2018
        {
2019 667 berkley
          pstmt.close();
2020 1217 tao
          //conn.close();
2021 629 berkley
          return true;
2022
        }
2023
        else
2024
        {
2025 667 berkley
          pstmt.close();
2026 1217 tao
          //conn.close();
2027 629 berkley
          return false;
2028
        }
2029
      }
2030
    }
2031
    catch(Exception e)
2032
    {
2033 2286 tao
      System.out.println("error in MetacatReplication.replToServer: " +
2034 675 berkley
                         e.getMessage());
2035 629 berkley
    }
2036 667 berkley
    finally
2037
    {
2038
      try
2039
      {
2040
        pstmt.close();
2041 1217 tao
        //conn.close();
2042
      }//try
2043 667 berkley
      catch(Exception ee)
2044 1217 tao
      {
2045 2663 sgarg
        logMetacat.error("Error in MetacatReplication.replToServer: "
2046
                                  +ee.getMessage());
2047 1217 tao
      }//catch
2048
      finally
2049
      {
2050
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2051
      }//finally
2052
    }//finally
2053 629 berkley
    return false;
2054
    //the default if this server does not exist is to not replicate to it.
2055
  }
2056 2286 tao
2057
2058 522 berkley
}