Project

General

Profile

« Previous | Next » 

Revision 561

Added by berkley over 23 years ago

added functionality to allow the replication servlet to assertain and insert user and group info into the local database. started implementation of insert replication handler (it is commented out in this commit)

View differences:

src/edu/ucsb/nceas/metacat/MetacatReplication.java
24 24
import oracle.xml.parser.v2.*;
25 25
import org.xml.sax.*;
26 26

  
27
public class MetacatReplication extends HttpServlet
27
public class MetacatReplication extends HttpServlet implements Runnable
28 28
{  
29 29
  private String deltaT;
30 30
  Timer replicationDaemon;
31
  MetaCatUtil util = new MetaCatUtil();
31
  private static MetaCatUtil util = new MetaCatUtil();
32
  private Vector fileLocks = new Vector();
33
  private Thread lockThread = null;
32 34
  
33 35
  /**
34 36
   * Initialize the servlet by creating appropriate database connections
......
126 128
        //handleGetDocumentAction().
127 129
        handleGetDocumentRequest(out, params, response);
128 130
      }
131
      else if(((String[])params.get("action"))[0].equals("getlock"))
132
      {
133
        handleGetLockRequest(out, params, response);
134
      }
135
      else if(((String[])params.get("action"))[0].equals("getdocumentinfo"))
136
      {
137
        handleGetDocumentInfoRequest(out, params, response);
138
      }
129 139
    }
130 140
  }
131 141
  
142
  /**
143
   * Grants or denies a lock to a requesting host.
144
   * The servlet parameters of interrest are:
145
   * docid: the docid of the file the lock is being requested for
146
   * currentdate: the timestamp of the document on the remote server
147
   * 
148
   */
149
  private void handleGetLockRequest(PrintWriter out, Hashtable params,
150
                                    HttpServletResponse response)
151
  {
152
    java.util.Date remoteDate = new java.util.Date();
153
    java.util.Date localDate = new java.util.Date();
154
    try
155
    {
156
      Connection conn = util.openDBConnection();
157
      String docid = ((String[])params.get("docid"))[0];
158
      String remoteDateStr = ((String[])params.get("updatedate"))[0];
159
      DocumentImpl requestDoc = new DocumentImpl(conn, docid);
160
    
161
      String localDateStr = requestDoc.getUpdateDate();
162
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
163
      ParsePosition pos = new ParsePosition(0);
164
      remoteDate = formatter.parse(remoteDateStr, pos);
165
      localDate = formatter.parse(localDateStr, pos);
166
      if(remoteDate.compareTo(localDate) >= 0)
167
      {
168
        if(!fileLocks.contains(docid))
169
        { //grant the lock
170
          fileLocks.add(0, docid); //insert at the beginning of the queue Vector
171
          //send a message back to the the remote host authorizing the insert
172
          out.println("<lockgranted><docid>" +docid+ "</docid></lockgranted>");
173
          lockThread = new Thread(this);
174
          lockThread.setPriority(Thread.MIN_PRIORITY);
175
          lockThread.start();
176
        }
177
        else
178
        { //deny the lock
179
          out.println("<filelocked><docid>" + docid + "</docid></filelocked>");
180
        }
181
      }
182
      else
183
      {//deny the lock.
184
        out.println("<outdatedfile><docid>" + docid + "</docid></filelocked>");
185
      }
186
      conn.close();
187
    }
188
    catch(Exception e)
189
    {
190
      System.out.println("error requesting file lock: " + e.getMessage());
191
    }
192
  }
193
  
194
  /**
195
   * Sends all of the xml_documents information encoded in xml to a requestor
196
   */
197
  private void handleGetDocumentInfoRequest(PrintWriter out, Hashtable params, 
198
                                        HttpServletResponse response)
199
  {
200
    String docid = ((String[])(params.get("docid")))[0];
201
    StringBuffer sb = new StringBuffer();
202
    try
203
    {
204
      Connection conn = util.openDBConnection();
205
      DocumentImpl doc = new DocumentImpl(conn, docid);
206
      sb.append("<documentinfo><docid>").append(docid);
207
      sb.append("</docid><docname>").append(doc.getDocname());
208
      sb.append("</docname><doctype>").append(doc.getDoctype());
209
      sb.append("</doctype><doctitle>").append(doc.getDocTitle());
210
      sb.append("</doctitle><user_owner>").append(doc.getUserowner());
211
      sb.append("</user_owner><user_updated>").append(doc.getUserupdated());
212
      sb.append("</user_updated><public_access>").append(doc.getPublicaccess());
213
      sb.append("</public_access></documentinfo>");
214
      response.setContentType("text/xml");
215
      out.println(sb.toString());
216
      conn.close();
217
    }
218
    catch (Exception e)
219
    {
220
      System.out.println("error in metacatReplication.handlegetdocumentinforequest: " + 
221
      e.getMessage());
222
    }
223
    
224
  }
225
  
226
  /**
227
   * Sends a document to a remote host
228
   */
132 229
  private void handleGetDocumentRequest(PrintWriter out, Hashtable params, 
133
                                   HttpServletResponse response)
230
                                        HttpServletResponse response)
134 231
  {
135 232
    try
136 233
    {
......
176 273
    java.util.Date update = new java.util.Date();
177 274
    ParsePosition pos = new ParsePosition(0);
178 275
    update = formatter.parse(updateStr, pos);
179
    //update = new java.util.Date(update.getTime() - 10000);
180 276
    String dateString = formatter.format(update);
181 277
    sql.append("select docid, date_updated, server_location from ");
182 278
    sql.append("xml_documents where date_updated > ");
183
    sql.append("to_date('").append(dateString).append("','YY-MM-DD HH24:MI:SS')");
279
    sql.append("to_date('").append(dateString);
280
    sql.append("','YY-MM-DD HH24:MI:SS')");
184 281
    //System.out.println("sql: " + sql.toString());
185 282
    
186 283
    //get any recently deleted documents
187 284
    StringBuffer delsql = new StringBuffer();
188
    delsql.append("select docid, date_created, server_location from ");
285
    delsql.append("select docid, date_updated, server_location from ");
189 286
    delsql.append("xml_revisions where docid not in (select docid from ");
190
    delsql.append("xml_documents) and date_created > to_date('");
287
    delsql.append("xml_documents) and date_updated > to_date('");
191 288
    delsql.append(dateString).append("','YY-MM-DD HH24:MI:SS')");
192 289

  
193 290
    try
......
247 344
      System.out.println("Exception in metacatReplication: " + e.getMessage());
248 345
    }
249 346
  }
347
  
348
  /**
349
   * This method is what is run when a seperate thread is broken off to handle
350
   * inserting a document from a remote replicated server.
351
   */
352
  public void run()
353
  {
354
    try
355
    {
356
      Thread.sleep(30000); //the lock will expire in 30 seconds
357
      fileLocks.remove(fileLocks.size() - 1);
358
      //the vector is treated as a FIFO queue.  If there are more than one lock
359
      //in the vector, the first one inserted will be removed.
360
    }
361
    catch(Exception e)
362
    {
363
      System.out.println("error in file lock thread: " + e.getMessage());
364
    }
365
  }
366
  
367
  /**
368
   * Returns the name of a server given a serverCode
369
   * @param serverCode the serverid of the server
370
   * @return the servername or null if the specified serverCode does not
371
   *         exist.
372
   */
373
  public static String getServer(int serverCode)
374
  {
375
    try
376
    {
377
      Connection conn = util.openDBConnection();
378
      PreparedStatement pstmt = conn.prepareStatement("select server from " +
379
                              "xml_replication where serverid = " + 
380
                              serverCode);
381
      pstmt.execute();
382
      ResultSet rs = pstmt.getResultSet();
383
      boolean tablehasrows = rs.next();
384
      if(tablehasrows)
385
      {
386
        conn.close();
387
        return rs.getString(1);
388
      }
389
      conn.close();
390
    }
391
    catch(Exception e)
392
    {
393
      System.out.println("Error in MetacatReplication.getServer: " + 
394
                          e.getMessage());
395
    }
396
    return null;
397
      //return null if the server does not exist
398
  }
250 399
}
src/edu/ucsb/nceas/metacat/DocumentImpl.java
21 21
import java.io.Reader;
22 22
import java.io.StringWriter;
23 23
import java.io.Writer;
24
import java.io.InputStreamReader;
24 25

  
25 26
import java.util.Iterator;
26 27
import java.util.Stack;
......
37 38
import org.xml.sax.SAXParseException;
38 39
import org.xml.sax.helpers.XMLReaderFactory;
39 40

  
41
import java.net.URL;
42

  
40 43
/**
41 44
 * A class that represents an XML document. It can be created with a simple
42 45
 * document identifier from a database connection.  It also will write an
......
56 59
  private String createdate = null;
57 60
  private String updatedate = null;
58 61
  private String system_id = null;
62
  private String userowner = null;
63
  private String userupdated = null;
64
  private int serverlocation;
65
  private int publicaccess; 
59 66
  private long rootnodeid;
60 67
  private ElementNode rootNode = null;
61 68
  private TreeSet nodeRecordList = null;
......
187 194
  public String getDocTitle() {
188 195
    return doctitle;
189 196
  }
197
  
198
  public String getUserowner() {
199
    return userowner;
200
  }
201
  
202
  public String getUserupdated() {
203
    return userupdated;
204
  }
205
  
206
  public int getServerlocation() {
207
    return serverlocation;
208
  }
209
  
210
  public int getPublicaccess() {
211
    return publicaccess;
212
  }
190 213

  
191

  
192 214
  /**
193 215
   * Print a string representation of the XML document
194 216
   */
......
375 397
    try {
376 398
      pstmt =
377 399
        conn.prepareStatement("SELECT docname, doctype, rootnodeid,doctitle, " +
378
                              "date_created, date_updated " + 
400
                              "date_created, date_updated, " + 
401
                              "user_owner, user_updated, server_location, " +
402
                              "public_access " +
379 403
                               "FROM xml_documents " +
380 404
                               "WHERE docid LIKE ?");
381 405
      // Bind the values to the query
......
385 409
      ResultSet rs = pstmt.getResultSet();
386 410
      boolean tableHasRows = rs.next();
387 411
      if (tableHasRows) {
388
        this.docname    = rs.getString(1);
389
        this.doctype    = rs.getString(2);
390
        this.rootnodeid = rs.getLong(3);
391
        this.doctitle   = rs.getString(4);
392
        this.createdate = rs.getString(5);
393
        this.updatedate = rs.getString(6);
412
        this.docname        = rs.getString(1);
413
        this.doctype        = rs.getString(2);
414
        this.rootnodeid     = rs.getLong(3);
415
        this.doctitle       = rs.getString(4);
416
        this.createdate     = rs.getString(5);
417
        this.updatedate     = rs.getString(6);
418
        this.userowner      = rs.getString(7);
419
        this.userupdated    = rs.getString(8);
420
        this.serverlocation = rs.getInt(9);
421
        this.publicaccess   = rs.getInt(10);
394 422
      } 
395 423
      pstmt.close();
396 424

  
......
699 727
                              String action, String docid, String user,
700 728
                              String group, int serverCode )
701 729
                throws Exception {
702
/*
703
    if(serverCode != 1)
730
System.out.println("outside of if: action: " + action + "servercode: " + serverCode);
731
    if(serverCode != 1 && action.equals("UPDATE"))
704 732
    { //if this document being written is not a resident of this server then
705 733
      //we need to try to get a lock from it's resident server.  If the
706 734
      //resident server will not give a lock then we send the user a message
707 735
      //saying that he/she needs to download a new copy of the file and
708 736
      //merge the differences manually.
737
System.out.println("in if: action: " + action + "servercode: " + serverCode);
738
      int istreamInt;
739
      char istreamChar;
740
      DocumentImpl newdoc = new DocumentImpl(conn, docid);
741
      String update = newdoc.getUpdateDate();
742
      String server = MetacatReplication.getServer(serverCode);
709 743
      
744
      URL u = new URL("http://" + server + "?action=getlock&updatedate=" + update +
745
                  "&docid=" + docid);
746
      InputStreamReader istream = new InputStreamReader(u.openStream());
747
      StringBuffer serverResponse = new StringBuffer();
748
      while((istreamInt = istream.read()) != -1)
749
      {
750
        istreamChar = (char)istreamInt;
751
        serverResponse.append(istreamChar);
752
      }
710 753
      
754
      String serverResStr = serverResponse.toString();
755
      String openingtag = serverResStr.substring(0, serverResStr.indexOf(">"));
756
      System.out.println("openingtag: " + openingtag);
757
      if(openingtag.equals("<lockgranted>"))
758
      {//the lock was granted go ahead with the insert
759
        
760
      }
761
      else if(openingtag.equals("<filelocked>"))
762
      {//the file is currently locked by another user
763
       //notify our user to wait a few minutes, check out a new copy and try
764
       //again.
765
        
766
      }
767
      else if(openingtag.equals("<outdatedfile>"))
768
      {//our file is outdated.  notify our user to check out a new copy of the
769
       //file and merge his version with the new version.
770
        
771
      }
711 772
    }
712
*/    
773
    
713 774
    // Determine if the docid is OK for INSERT or UPDATE
714 775
    AccessionNumber ac = new AccessionNumber(conn);
715 776
    String newdocid = ac.generate(docid, action);
src/edu/ucsb/nceas/metacat/ReplMessageHandler.java
27 27
import org.xml.sax.helpers.DefaultHandler;
28 28

  
29 29
/** 
30
 * A database aware Class implementing callback bethods for the SAX parser to
30
 * A Class implementing callback bethods for the SAX parser to
31 31
 * call when processing the XML messages from the replication handler
32 32
 */
33 33
public class ReplMessageHandler extends DefaultHandler 
src/edu/ucsb/nceas/metacat/ReplicationHandler.java
29 29
import org.xml.sax.SAXException;
30 30
import org.xml.sax.SAXParseException;
31 31
import org.xml.sax.helpers.XMLReaderFactory;
32
import org.xml.sax.helpers.DefaultHandler;
32 33

  
34

  
35

  
33 36
/**
34 37
 * This class handles deltaT replication checking.  Whenever this TimerTask
35 38
 * is fired it checks each server in xml_replication for updates and updates
......
186 189
            //work as a param to this method but it doesn'.  I don't know why
187 190
            //but putting a string reader there works but not an 
188 191
            //inputStreamReader.
192
            DocInfoHandler dih = new DocInfoHandler();
193
            XMLReader docinfoParser = initParser(dih);
194
            URL docinfoUrl = new URL("http://" + docServer + 
195
                                     "?action=getdocumentinfo&docid=" +
196
                                     docid);
197
            InputStreamReader isr = new InputStreamReader(
198
                                        docinfoUrl.openStream());
199
            StringBuffer docInfoBuffer = new StringBuffer();
200
            while((istreamInt = isr.read()) != 1)
201
            {
202
              istreamChar = (char)istreamInt;
203
              docInfoBuffer.append(istreamChar);
204
            }
205
            
206
            docinfoParser.parse(new InputSource(new StringReader(
207
                                                docInfoBuffer.toString())));
208
            Hashtable docinfoHash = dih.getDocInfo();
209
            
189 210
            String newDocid = DocumentImpl.write(conn, 
190
                                               new StringReader(serverResponse.toString())
191
                                               /*getDocIstream*/, 
192
                                               action, 
193
                                               docid, null, null, serverCode);
211
                               new StringReader(serverResponse.toString())
212
                               /*getDocIstream*/, 
213
                               action, 
214
                               docid, (String)docinfoHash.get("user_owner"), 
215
                               (String)docinfoHash.get("user_owner"), 
216
                               serverCode);
194 217
            System.out.println("newDocid: " + newDocid + " " + action + "ED");
195 218
          }
196 219
        }
......
201 224
          String docid = (String)w.elementAt(0);
202 225
          
203 226
          DocumentImpl.delete(conn, docid, null, null);
227
          System.out.println("Document " + docid + " deleted.");
204 228
        }
205 229
      }
206 230

  
......
267 291
  /**
268 292
   * Method to initialize the message parser
269 293
   */
270
  private static XMLReader initParser(ReplMessageHandler rmh)
294
  private static XMLReader initParser(DefaultHandler dh)
271 295
          throws Exception
272 296
  {
273 297
    XMLReader parser = null;
274 298

  
275 299
    try {
276
      ContentHandler chandler = rmh;
300
      ContentHandler chandler = dh;
277 301

  
278 302
      // Get an instance of the parser
279 303
      MetaCatUtil util = new MetaCatUtil();

Also available in: Unified diff