Project

General

Profile

« Previous | Next » 

Revision 1055

Added by Jing Tao over 22 years ago

Add three methods into this class. One is named getServerCode, to given a server name, it return server code in xml_replication table.
One named insertServerIntoReplicationTable, if a server is not in the server list, it will insert it.
One is named WriteReplication, this method will be used in forceReplication. It delete the replication code in it.

View differences:

src/edu/ucsb/nceas/metacat/DocumentImpl.java
240 240
   * Register a document that resides on the filesystem with the database.
241 241
   * (ie, just an entry in xml_documents, nothing in xml_nodes).
242 242
   * Creates a reference to a filesystem document (used for non-xml data files).
243
   *
243
   * This class only be called in MetaCatServerlet.
244 244
   * @param conn the JDBC Connection to which all information is written
245 245
   * @param docname - the name of DTD, i.e. the name immediately following 
246 246
   *        the DOCTYPE keyword ( should be the root element name ) or
......
328 328
    }    
329 329
  }
330 330
  
331
    /**
332
   * Register a document that resides on the filesystem with the database.
333
   * (ie, just an entry in xml_documents, nothing in xml_nodes).
334
   * Creates a reference to a filesystem document (used for non-xml data files)
335
   * This method will be called for register data file in xml_documents in 
336
   * Replication.
337
   * This method is revised from registerDocument.
338
   *
339
   * @param conn the JDBC Connection to which all information is written
340
   * @param docname - the name of DTD, i.e. the name immediately following 
341
   *        the DOCTYPE keyword ( should be the root element name ) or
342
   *        the root element name if no DOCTYPE declaration provided
343
   *        (Oracle's and IBM parsers are not aware if it is not the 
344
   *        root element name)
345
   * @param doctype - Public ID of the DTD, i.e. the name immediately 
346
   *                  following the PUBLIC keyword in DOCTYPE declaration or
347
   *                  the docname if no Public ID provided or
348
   *                  null if no DOCTYPE declaration provided
349
   * @param accnum the accession number to use for the INSERT OR UPDATE, which 
350
   *               includes a revision number for this revision of the document 
351
   *               (e.g., knb.1.1)
352
   * @param user the user that owns the document
353
   * @param serverCode the serverid from xml_replication on which this document
354
   *        resides.
355
   */
356
  public static void registerDocumentInReplication(
357
                     String docname, String doctype, String accnum, 
358
                     String user, int serverCode)
359
                     throws SQLException, AccessionNumberException, Exception
360
  {
361
    Connection dbconn = null;
362
    MetaCatUtil util = new MetaCatUtil();
363
    AccessionNumber ac;
364
    try {
365
      dbconn = util.openDBConnection();
366
      String docIdWithoutRev=MetaCatUtil.getDocIdFromString(accnum);
367
      int userSpecifyRev=MetaCatUtil.getVersionFromString(accnum);
368
      int revInDataBase=getLatestRevisionNumber(dbconn, docIdWithoutRev);
369
      //revIndataBase=-1, there is no record in xml_documents table
370
      //the data file is a new one, inert it into table
371
      //user specified rev should be great than 0
372
      if (revInDataBase==-1 && userSpecifyRev>0 )
373
      {
374
        //ture means for replication
375
        ac = new AccessionNumber(dbconn, accnum, "insert");
376
      }
377
      //rev is greater the last revsion number and revInDataBase isn't -1
378
      // it is a updated data file
379
      else if (userSpecifyRev>revInDataBase && revInDataBase>0)
380
      {
381
        
382
        //archive the old entry 
383
        archiveDocRevision(dbconn, docIdWithoutRev, user);
384
        //delete the old entry in xml_documents
385
        deleteXMLDocuments(dbconn, docIdWithoutRev);
386
        ac = new AccessionNumber(dbconn, accnum, "update");
387
      }
388
      //other situation
389
      else
390
      {
391
        
392
        throw new Exception("Revision number couldn't be "
393
                    +userSpecifyRev);
394
      }
395
      String docid = ac.getDocid();
396
      String rev = ac.getRev();
397
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
398
      Date localtime = new Date();
399
      String dateString = formatter.format(localtime);
400
  
401
      String sqlDateString = "to_date('" + dateString + 
402
                                          "', 'YY-MM-DD HH24:MI:SS')";
403
  
404
      StringBuffer sql = new StringBuffer();
405
      sql.append("insert into xml_documents (docid, docname, doctype, ");
406
      sql.append("user_owner, user_updated, server_location, rev,date_created");
407
      sql.append(", date_updated, public_access) values ('");
408
      sql.append(docid).append("','");
409
      sql.append(docname).append("','");
410
      sql.append(doctype).append("','");
411
      sql.append(user).append("','");
412
      sql.append(user).append("','");
413
      sql.append(serverCode).append("','");
414
      sql.append(rev).append("',");
415
      sql.append(sqlDateString).append(",");
416
      sql.append(sqlDateString).append(",");
417
      sql.append("'0')");
418
      PreparedStatement pstmt = dbconn.prepareStatement(sql.toString());
419
      pstmt.execute();
420
      pstmt.close();
421
      dbconn.close();
422
    } finally {
423
      util.returnConnection(dbconn);
424
    }    
425
  }
426
  
331 427
 /**
332 428
   * This method will register a data file entry in xml_documents and save a
333
   * data file input Stream into file system..
429
   * data file input Stream into file system.. It is only used in force 
430
   * replication
334 431
   *
335 432
   * @param  input, the input stream which contain the file content.
336 433
   * @param  , the input stream which contain the file content
......
360 457
    if (getDataFileLockGrant(accnum))
361 458
    {
362 459
      //register data file into xml_documents table
363
      registerDocument(docname, doctype, accnum, user, serverCode);
460
      registerDocumentInReplication(docname, doctype, accnum, user, serverCode);
364 461
      //write inputstream into file system.
365 462
      File dataDirectory = new File(filePath);
366 463
      File newFile = new File(dataDirectory, accnum); 
......
384 481
	    outPut.close();
385 482
	    fos.close();
386 483
      //force replication to other server
484
      /*during replciation, don't need force replication again.
387 485
      MetaCatUtil util = new MetaCatUtil();
388 486
      if ((util.getOption("replicationdata")).equals("on"))
389 487
      {
390 488
        Connection dbConn = util.getConnection();
391
        //this is local server, force replication to every server in its server
392
        //list
489
       
393 490
        if (serverCode==1)
394 491
        {
395 492
          
396 493
          ForceReplicationHandler frh = new ForceReplicationHandler(accnum,
397 494
                  "insert",false,ReplicationHandler.buildServerList(dbConn));
398 495
          util.returnConnection(dbConn);
399
        }//if
496
        }
400 497
        else
401 498
        {
402
          //if it is super hub, replication to server list
499
          
403 500
          if ((util.getOption("hub")).equals("super"))
404 501
          {
405 502
            ForceReplicationHandler frh = new ForceReplicationHandler(accnum, 
......
408 505
          }
409 506
          else
410 507
          {
411
            //only replicate to home host of the document
508
            
412 509
            String docId=util.getDocIdFromString(accnum);
413 510
            ForceReplicationHandler frh = new ForceReplicationHandler(accnum, 
414 511
                true, ReplicationHandler.getHomeServer(docId));
415 512
          }
416 513
        }
417
      }//if
514
      }*/
418 515
    }//if
419 516
 }
420 517
  
421
 /**
422
   * unRegister a an XML file (data file) from the database (actually, 
423
   * just make it a revision in the xml_revisions table and delete it
424
   * from xml_documents table). 
425
   *
426
   * @param docid the ID of the document to be deleted from the database
427
   */
428
  public static void unRegisterDocument( Connection conn, String accnum,
429
                                 String user, String[] groups )
430
                throws Exception 
431
  {
432
    
433 518

  
434
    // NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
435
    AccessionNumber ac = new AccessionNumber(conn, accnum, "DELETE");
436
    String docid = ac.getDocid();
437
    String rev = ac.getRev();
438
    
439

  
440
    // check for 'write' permission for 'user' to delete this document
441
    if ( !hasPermission(conn, user, groups, docid) ) {
442
      throw new Exception("User " + user + 
443
              " does not have permission to delete XML Document #" + accnum);
444
    }
445

  
446
    conn.setAutoCommit(false);
447
    // Copy the record to the xml_revisions table
448
    DocumentImpl.archiveDocRevision( conn, docid, user );
449

  
450
    // Now delete it from the xml_documents table
451
    
452
    Statement stmt = conn.createStatement();
453
    //stmt.execute("DELETE FROM xml_access WHERE docid = '" + docid + "'");
454
    stmt.execute("DELETE FROM xml_documents WHERE docid = '" + docid + "'");
455
    stmt.close();
456
    conn.commit();
457
    conn.setAutoCommit(true);
458
   
459
    
460
  }
461 519
  
462 520
  public static boolean getDataFileLockGrant(String accnum) 
463 521
                                                  throws Exception
......
617 675
    return serverlocation;
618 676
  }
619 677
  
678
  public String getHomeServer(String docId)
679
  {
680
    String homeServer=null;
681
    Connection conn = null;
682
    MetaCatUtil ut=new MetaCatUtil();
683
    docId=ut.getDocIdFromString(docId);
684
    ut.debugMessage("docId: "+docId, 50);
685
    PreparedStatement pstmt=null;
686
    //PreparedStatement getServerStatement=null;
687
    int serverLocation;
688
    try
689
    {
690
      conn=ut.getConnection();
691
      //get a server location from xml_document table
692
      pstmt = conn.prepareStatement("select server_location from "
693
                                +"xml_documents where docid = ?");
694
      pstmt.setString(1, docId);
695
      pstmt.execute();
696
      ResultSet serverName = pstmt.getResultSet();
697
      //get a server location
698
      if(serverName.next())
699
      {
700
        serverLocation=serverName.getInt(1);
701
        ut.debugMessage("serverLocation: "+serverLocation, 50);
702
        pstmt.close();
703
      }
704
      else
705
      {
706
        pstmt.close();
707
        ut.returnConnection(conn);
708
        return homeServer;
709
      }
710
      pstmt = conn.prepareStatement("select server " +
711
                        "from xml_replication where serverid = ?");
712
                        
713
      
714
      pstmt.setInt(1, serverLocation);
715
      pstmt.execute();
716
      ResultSet rs = pstmt.getResultSet();
717
      boolean tableHasRows = rs.next();
718
      if (tableHasRows)
719
      {
720
        
721
          String server = rs.getString(1);
722
          //get homeserver name
723
          if(!server.equals("localhost"))
724
          {
725
            homeServer=server;
726
          }
727
          else
728
          {
729
            homeServer=ut.getLocalReplicationServerName();
730
          }
731
          ut.debugMessage("server: "+homeServer, 50);
732
        
733
      }
734
      else
735
      {
736
        pstmt.close();
737
        ut.returnConnection(conn);
738
        return homeServer;
739
      }
740
      pstmt.close();
741
    }
742
    catch(Exception e)
743
    {
744
      System.out.println("error in DocumentIpml.getHomerserver(): " +
745
                         e.getMessage());
746
    }
747
    finally
748
    {
749
      try
750
      {
751
        pstmt.close();
752
        ut.returnConnection(conn);
753
      }
754
      catch (Exception ee)
755
      {
756
      }
757
      
758
    }
759
   
760
    return homeServer;
761
  }
762
 
620 763
  public String getPublicaccess() {
621 764
    return publicaccess;
622 765
  }
......
1270 1413
    String docid = ac.getDocid();
1271 1414
    String rev = ac.getRev();
1272 1415
    MetaCatUtil.debugMessage("action: " + action + " servercode: " + 
1273
                             serverCode + " override: " + override);
1416
                             serverCode + " override: " + override, 10);
1274 1417
                        
1275 1418
    if((serverCode != 1 && action.equals("UPDATE")) && !override)
1276 1419
    { //if this document being written is not a resident of this server then
......
1396 1539
  }
1397 1540

  
1398 1541
  /**
1542
   * Write an XML file to the database during replication
1543
   *
1544
   * @param conn the JDBC connection to the database
1545
   * @param xml the xml stream to be loaded into the database
1546
   * @param pub flag for public "read" access on xml document
1547
   * @param dtd the dtd to be uploaded on server's file system
1548
   * @param action the action to be performed (INSERT or UPDATE)
1549
   * @param accnum the docid + rev# to use on INSERT or UPDATE
1550
   * @param user the user that owns the document
1551
   * @param groups the groups to which user belongs
1552
   * @param homeServer the name of server which the document origanlly create
1553
   * @param validate, if the xml document is valid or not
1554
   */
1555

  
1556
  public static String writeReplication( Connection conn,Reader xml,String pub,
1557
                Reader dtd, String action, String accnum, String user,
1558
                            String[] groups,String homeServer, boolean validate)
1559
                throws Exception
1560
  {
1561
    // NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
1562
    MetaCatUtil util = new MetaCatUtil();
1563
    AccessionNumber ac = new AccessionNumber(conn, accnum, action);
1564
    String docid = ac.getDocid();
1565
    String rev = ac.getRev();
1566
    int serverCode=-2;
1567
    //get server code for the home server
1568
    serverCode=getServerCode(homeServer);
1569
    //if the server is not in the xml replication table, insert it.
1570
    if (serverCode==-1)
1571
    {
1572
      insertServerIntoReplicationTable(homeServer);
1573
      //get server code again
1574
      serverCode=getServerCode(homeServer);
1575
    }
1576
      
1577
    MetaCatUtil.debugMessage("action: " + action + " servercode: " + 
1578
                             serverCode, 10);
1579
                        
1580
    if((serverCode != 1 && action.equals("UPDATE")) )
1581
    { //if this document being written is not a resident of this server then
1582
      //we need to try to get a lock from it's resident server.  If the
1583
      //resident server will not give a lock then we send the user a message
1584
      //saying that he/she needs to download a new copy of the file and
1585
      //merge the differences manually.
1586
      int istreamInt; 
1587
      char istreamChar;
1588
      DocumentIdentifier id = new DocumentIdentifier(accnum);
1589
      String updaterev = id.getRev();
1590
      String server = MetacatReplication.getServer(serverCode);
1591
      MetacatReplication.replLog("attempting to lock " + accnum);
1592
      URL u = new URL("https://" + server + "?server="
1593
           +util.getLocalReplicationServerName()+"&action=getlock&updaterev=" 
1594
           +updaterev + "&docid=" + docid);
1595
      //System.out.println("sending message: " + u.toString());
1596
      String serverResStr = MetacatReplication.getURLContent(u);
1597
      String openingtag =serverResStr.substring(0, serverResStr.indexOf(">")+1);
1598
      if(openingtag.equals("<lockgranted>"))
1599
      {//the lock was granted go ahead with the insert
1600
        try 
1601
        {
1602
          //System.out.println("In lockgranted");
1603
          MetacatReplication.replLog("lock granted for " + accnum + " from " +
1604
                                      server);
1605
          XMLReader parser = initializeParser(conn, action, docid, updaterev,
1606
                                  validate, user, groups, pub, serverCode, dtd);
1607
          conn.setAutoCommit(false);
1608
          parser.parse(new InputSource(xml)); 
1609
          conn.commit();
1610
          conn.setAutoCommit(true);
1611
        } 
1612
        catch (Exception e) 
1613
        {
1614
          conn.rollback();
1615
          conn.setAutoCommit(true);
1616
          throw e;
1617
        }
1618
        return (accnum);
1619
      }
1620

  
1621
      else if(openingtag.equals("<filelocked>"))
1622
      {//the file is currently locked by another user
1623
       //notify our user to wait a few minutes, check out a new copy and try
1624
       //again.
1625
        //System.out.println("file locked");
1626
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
1627
                                   server + " reason: file already locked");
1628
        throw new Exception("The file specified is already locked by another " +
1629
                            "user.  Please wait 30 seconds, checkout the " +
1630
                            "newer document, merge your changes and try " +
1631
                            "again.");
1632
      }
1633
      else if(openingtag.equals("<outdatedfile>"))
1634
      {//our file is outdated.  notify our user to check out a new copy of the
1635
       //file and merge his version with the new version.
1636
        //System.out.println("outdated file");
1637
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
1638
                                    server + " reason: local file outdated");
1639
        throw new Exception("The file you are trying to update is an outdated" +
1640
                            " version.  Please checkout the newest document, " +
1641
                            "merge your changes and try again.");
1642
      }
1643
    }
1644
    
1645
    if ( action.equals("UPDATE") ) {
1646
      // check for 'write' permission for 'user' to update this document
1647

  
1648
      if ( !hasPermission(conn, user, groups, docid) ) {
1649
        throw new Exception("User " + user + 
1650
              " does not have permission to update XML Document #" + accnum);
1651
      }          
1652
    }
1653

  
1654
    try 
1655
    { 
1656
      
1657
      XMLReader parser = initializeParser(conn, action, docid, rev, validate,
1658
                                          user, groups, pub, serverCode, dtd);
1659
      conn.setAutoCommit(false);
1660
      parser.parse(new InputSource(xml));
1661
      conn.commit();
1662
      conn.setAutoCommit(true);
1663
    } 
1664
    catch (Exception e) 
1665
    {
1666
      conn.rollback();
1667
      conn.setAutoCommit(true);
1668
      throw e;
1669
    }
1670

  
1671
    return(accnum);
1672
  }
1673

  
1674
  
1675
  /**
1399 1676
   * Delete an XML file from the database (actually, just make it a revision
1400 1677
   * in the xml_revisions table)
1401 1678
   *
......
1637 1914
      
1638 1915
    return serverLocation;
1639 1916
  }
1917
  
1640 1918
  /**
1919
   * Given a server name, return its servercode in xml_replication table.
1920
   * If no server is found, -1 will return
1921
   * @param serverName, 
1922
   */
1923
  private static int getServerCode(String serverName) 
1924
  {
1925
    PreparedStatement pStmt=null;
1926
    int serverLocation=-2;
1927
    Connection dbConn = null;
1928
    MetaCatUtil util = new MetaCatUtil();
1929
    
1930
    
1931
    //we should consider about local host too
1932
    if (serverName.equals(util.getLocalReplicationServerName()))
1933
    { 
1934
      serverLocation=1;
1935
      return serverLocation;
1936
    }
1937
    
1938
   
1939
    try
1940
    {
1941
      //check xml_replication table
1942
      dbConn=util.getConnection();
1943
      pStmt = dbConn.prepareStatement
1944
      ("SELECT serverid FROM xml_replication WHERE server='" + serverName +"'");
1945
      pStmt.execute();
1946

  
1947
      ResultSet rs = pStmt.getResultSet();
1948
      boolean hasRow = rs.next();
1949
      //if there is entry in xml_replication, get the serverid
1950
      if (hasRow)
1951
      {
1952
        serverLocation = rs.getInt(1);
1953
        pStmt.close();
1954
      }
1955
      else
1956
      {
1957
        // if htere is no entry in xml_replication, -1 will return
1958
        serverLocation=-1;
1959
        pStmt.close();
1960
      }
1961
    }
1962
    catch (Exception e)
1963
    {
1964
      util.debugMessage("Error in DocumentImpl.getServerCode(): "
1965
                                    +e.getMessage(), 30);
1966
    }
1967
    finally
1968
    {
1969
      try
1970
      {
1971
        util.returnConnection(dbConn);
1972
      }
1973
      catch (Exception ee)
1974
      {}
1975
    }
1976
                 
1977
      
1978
    return serverLocation;
1979
  }
1980
  
1981
  /**
1982
   * Insert a server into xml_replcation table
1983
   * @param server, the name of server 
1984
   */
1985
  private static void  insertServerIntoReplicationTable(String server)
1986
  {
1987
    PreparedStatement pStmt=null;
1988
    Connection dbConn = null;
1989
    int replicate = 1;
1990
    MetaCatUtil util = new MetaCatUtil();
1991
    try
1992
    {
1993
       dbConn=util.getConnection();
1994
       pStmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
1995
                                      "(server, last_checked, replicate) " +
1996
                                      "VALUES ('" + server + "', to_date(" +
1997
                                      "'01/01/00', 'MM/DD/YY'), '" +
1998
                                      replicate + "')");
1999
        pStmt.execute();
2000
        pStmt.close();
2001
        dbConn.commit();
2002
    }
2003
    catch (Exception e)
2004
    {
2005
      util.debugMessage("Error in DocumentImpl.getServerCode(): "
2006
                                    +e.getMessage(), 30);
2007
    }
2008
    finally
2009
    {
2010
      try
2011
      {
2012
        pStmt.close();
2013
        util.returnConnection(dbConn);
2014
      }
2015
      catch (Exception ee)
2016
      {}
2017
    }
2018

  
2019
  }
2020
  
2021
  
2022
  /**
1641 2023
   * the main routine used to test the DBWriter utility.
1642 2024
   * <p>
1643 2025
   * Usage: java DocumentImpl <-f filename -a action -d docid>

Also available in: Unified diff