Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class to asyncronously force the replication of each server
4
 *             that has an entry in the xml_replication table.  When run,
5
 *             this thread communicates with each server in the list and
6
 *             solicites a read of an updated or newly inserted document
7
 *             with a certain docid.
8
 *  Copyright: 2000 Regents of the University of California and the
9
 *             National Center for Ecological Analysis and Synthesis
10
 *    Authors: Chad Berkley
11
 *
12
 *   '$Author: tao $'
13
 *     '$Date: 2007-04-12 18:34:59 -0700 (Thu, 12 Apr 2007) $'
14
 * '$Revision: 3230 $'
15
 *
16
 * This program is free software; you can redistribute it and/or modify
17
 * it under the terms of the GNU General Public License as published by
18
 * the Free Software Foundation; either version 2 of the License, or
19
 * (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
 */
30

    
31
package edu.ucsb.nceas.metacat;
32

    
33
import java.util.*;
34
import java.io.*;
35
import java.sql.*;
36
import java.net.*;
37
import java.lang.*;
38
import java.text.*;
39

    
40
import org.apache.log4j.Logger;
41

    
42
/**
43
 * A class to asyncronously force the replication of each server
44
 * that has an entry in the xml_replication table.  When run,
45
 * this thread communicates with each server in the list and
46
 * solicites a read of an updated or newly inserted document
47
 * with a certain docid.
48
 */
49
public class ForceReplicationHandler implements Runnable
50
{
51
  private Thread btThread;
52
  private MetaCatUtil util = new MetaCatUtil();
53
  private String docid;
54
  private String action;
55
  private boolean xmlDocument;
56
  private boolean dbactionFlag = true;
57
  private ReplicationServerList serverLists = null;//Serverlist
58
  private int homeServerCode = 0; // home server code for the docid
59
  // When a metacat A got forcereplication
60
  // notification from B, then A will update its record. And A will notification
61
  // other metacat in its serverlist to update this docid if A is a hub. But we
62
  // don't want A to notify B again. B is nofitification of A
63
  private String notificationServer = null;
64
  private Logger logMetacat = Logger.getLogger(ForceReplicationHandler.class);
65

    
66
  //constant
67
  public static final String DELETE = "delete";
68

    
69

    
70

    
71
  /**
72
   * Constructor of ForceReplicationHandler
73
   * @param docid the docid to force replicate
74
   * @param the action that is being performed on the document (either
75
   *        INSERT or UPDATE)
76
   * @param xml the docid is a xml document or not (data file)
77
   * @param notificationServer, when a metacat A got forcereplication
78
   * notification from B, then A will update its record. And A will notification
79
   * other metacat in its serverlist to update this docid if A is a hub. But we
80
   * don't want A to notify B again. B is nofitification of A.
81
   */
82
  public ForceReplicationHandler(String docid, String action, boolean xml,
83
                                                   String myNotificationServer)
84
  {
85
    this.docid = docid;
86
    this.action = action;
87
    this.xmlDocument =xml;
88
    // Build a severLists from xml_replication table
89
    this.serverLists = new ReplicationServerList();
90
    // Get sever code for this docid
91
    try
92
    {
93
      this.homeServerCode = MetacatReplication.getHomeServerCodeForDocId(docid);
94
    }//try
95
    catch (Exception e)
96
    {
97
      logMetacat.error("Error in ForceReplicationHandle(): "
98
                                                          +e.getMessage());
99
    }//catch
100
    // Get the notification server
101
    this.notificationServer = myNotificationServer;
102

    
103
    if(this.action.equals(""))
104
    {
105
      dbactionFlag = false;
106
    }
107

    
108
    btThread = new Thread(this);
109
    btThread.setPriority(Thread.MIN_PRIORITY);
110
    btThread.start();
111
  }
112

    
113
  /**
114
   * Use this constructor when the action is implied.
115
   */
116
  public ForceReplicationHandler(String docid, boolean xml,
117
                                                String myNotificationServer )
118
  {
119
    this.docid = docid;
120
    this.xmlDocument = xml;
121
    dbactionFlag = false;
122
    // Build a severLists from xml_replication table
123
    this.serverLists = new ReplicationServerList();
124
    // Get home server code for this doicd
125
    try
126
    {
127
      this.homeServerCode = MetacatReplication.getHomeServerCodeForDocId(docid);
128
    }
129
     catch (Exception e)
130
    {
131
      logMetacat.error("Error in ForceReplicationHandle(): "
132
                                                          +e.getMessage());
133
    }//catch
134
    // Get notification server
135
    this.notificationServer = myNotificationServer;
136
    btThread = new Thread(this);
137
    btThread.setPriority(Thread.MIN_PRIORITY);
138
    btThread.start();
139
  }
140

    
141
  /**
142
   * Method to send force replication command to other server to get
143
   * a new or updated docid
144
   */
145
  public void run()
146
  {
147

    
148
    
149
      // URL for notifcation
150
      URL comeAndGetIt = null;
151
      // If no server in xml_replication table, metacat don't need do anything
152
      if (serverLists.isEmpty())
153
      {
154
        return;
155
      }
156

    
157
      // Thread seelping for some seconds to make sure the document was insert
158
      // into the database before we send force replication request
159
      int sleepTime = Integer.parseInt
160
                         (MetaCatUtil.getOption("forcereplicationwaitingtime"));
161
      try
162
      {
163
        Thread.sleep(sleepTime);
164
      }
165
      catch(Exception ee)
166
      {
167
        logMetacat.error("Couldn't sleep in force replication");
168
      }
169
      logMetacat.info("notification server:"+notificationServer);
170
      // Check every server in the serverlists
171
      for (int i=0; i<serverLists.size(); i++)
172
      {
173
        //Set comeAndGetIt null
174
        comeAndGetIt = null;
175
         // Get ReplicationServer object in index i
176
        ReplicationServer replicationServer = serverLists.serverAt(i);
177
        // Get this ReplicationServer 's name
178
        String server = replicationServer.getServerName();
179
        try
180
        {
181
        
182

    
183
        // If the server is the notification server, we don't notify it back
184
        // again, if server is null we don't replication it
185
        if (server!=null && !server.equals(notificationServer))
186
        {
187

    
188
          if(dbactionFlag)
189
          {
190
            // xml documents and server can replicate xml doucment
191
            if (xmlDocument && replicationServer.getReplication())
192
            {
193
              // If this docid's homeserver is localhost, replicate it
194
              if (homeServerCode==1)
195
              {
196
                MetacatReplication.replLog("force xml replicating to "
197
                                                                    + server);
198
                comeAndGetIt = new URL("https://" + server +
199
                                 "?action=forcereplicate&server=" +
200
                                  util.getLocalReplicationServerName()+
201
                                 "&docid=" + docid + "&dbaction=" +
202
                                  action);
203
                //over write the url for delete
204
                if (action != null && action.equals(DELETE))
205
                {
206
                  comeAndGetIt = new URL("https://" + server + "?action=" +
207
                                   MetacatReplication.FORCEREPLICATEDELETE +
208
                                  "&docid=" + docid +"&server="+ util.getLocalReplicationServerName());
209

    
210
                }
211
              }//if servercode==1
212
              else if (replicationServer.getHub()||
213
                   server.equals(MetacatReplication.
214
                                  getServerNameForServerCode(homeServerCode)))
215
              {
216
                // If the docid's home server is not local host, but local host
217
                // is a hub of this server, replicate the docid too.
218
                // If the server is homeserver of the docid, replication it too
219
                MetacatReplication.replLog("force xml replicating to "
220
                                                                    + server);
221
                comeAndGetIt = new URL("https://" + server +
222
                                 "?action=forcereplicate&server=" +
223
                                 util.getLocalReplicationServerName() +
224
                                 "&docid=" + docid + "&dbaction=" +
225
                                  action);
226
                //over write the url for delete
227
               if (action != null && action.equals(DELETE))
228
               {
229
                  comeAndGetIt = new URL("https://" + server + "?action=" +
230
                            MetacatReplication.FORCEREPLICATEDELETE +
231
                           "&docid=" + docid+"&server="+ util.getLocalReplicationServerName());
232

    
233
                }
234
              }//else
235

    
236
            }//if xmlDocument
237
            //It is data file and configured to handle data replication
238
            else if (replicationServer.getDataReplication())
239
            {
240
              // If the docid's home server is local host, replicate the docid
241
              if (homeServerCode==1)
242
              {
243
                MetacatReplication.replLog("force data replicating to "
244
                                                                      + server);
245
                comeAndGetIt = new URL("https://" + server +
246
                                 "?action=forcereplicatedatafile&server=" +
247
                                 util.getLocalReplicationServerName() +
248
                                 "&docid=" + docid + "&dbaction=" +
249
                                  action);
250
                //over write the url for delete
251
               if (action != null && action.equals(DELETE))
252
               {
253
                 comeAndGetIt = new URL("https://" + server + "?action=" +
254
                                 MetacatReplication.FORCEREPLICATEDELETE +
255
                                 "&docid=" + docid +"&server="+ util.getLocalReplicationServerName());
256

    
257
               }
258

    
259
              }//if serverCode==1
260
              else if (replicationServer.getHub()||
261
                server.equals(MetacatReplication.
262
                                    getServerNameForServerCode(homeServerCode)))
263
              {
264
                // If the docid's home server is not local host, but local host
265
                // is a hub of this server, replicate the docid too.
266
                // If the server is homeserver of the docid replication it too
267
                 MetacatReplication.replLog("force data replicating to "
268
                                                                      + server);
269
                comeAndGetIt = new URL("https://" + server +
270
                                 "?action=forcereplicatedatafile&server=" +
271
                                 util.getLocalReplicationServerName() +
272
                                 "&docid=" + docid + "&dbaction=" +
273
                                  action);
274
                //over write the url for delete
275
               if (action != null && action.equals(DELETE))
276
               {
277
                  comeAndGetIt = new URL("https://" + server + "?action=" +
278
                         MetacatReplication.FORCEREPLICATEDELETE +
279
                        "&docid=" + docid+"&server="+ util.getLocalReplicationServerName());
280

    
281
               }
282

    
283
              }//else if servercode==1
284
            }//else if data file
285

    
286
          }//if has explicite action
287
          else
288
          { // has implicite action
289
            MetacatReplication.replLog("force replicating (default action) to )"
290
                                                + server);
291
            // this docid is xml documents and can replicate xml doucment
292
            if (xmlDocument && replicationServer.getReplication())
293
            {
294
              // If homeserver of this doicd is local, replicate it
295
              if (homeServerCode ==1)
296
              {
297
                comeAndGetIt = new URL("https://" + server +
298
                                 "?action=forcereplicate&server=" +
299
                                 util.getLocalReplicationServerName()+
300
                                 "&docid=" + docid);
301

    
302
              }//if homeserver ==1
303
              else if (replicationServer.getHub()||
304
                   server.equals(MetacatReplication.
305
                   getServerNameForServerCode(homeServerCode)))
306
              {
307
                // If home server of this docid is not local host, but local
308
                // host is a hub for this server, replicate this doicd
309
                // If the server is homeserver of the docid, replication it too
310
                comeAndGetIt = new URL("https://" + server +
311
                                 "?action=forcereplicate&server=" +
312
                                 util.getLocalReplicationServerName() +
313
                                 "&docid=" + docid);
314

    
315
              }//else if
316

    
317
            }//if xmlDoucment
318
            else if (replicationServer.getDataReplication())
319
            { //It is datafile and server is configured to replicate data file
320

    
321
              //if home server is local host, replicate the data file
322
              if (homeServerCode ==1)
323
              {
324
                comeAndGetIt = new URL("https://" + server +
325
                                 "?action=forcereplicatedatafile&server=" +
326
                                 util.getLocalReplicationServerName() +
327
                                 "&docid=" + docid);
328
              }//if
329
              else if (replicationServer.getHub()||
330
                          server.equals(MetacatReplication.
331
                          getServerNameForServerCode(homeServerCode)))
332
              {
333
                // If home server is not local host, but the local host is a hub
334
                // For this server, replicate the data file
335
                // If the server is homeserver of the docid, replication it too
336
                comeAndGetIt = new URL("https://" + server +
337
                                 "?action=forcereplicatedatafile&server=" +
338
                                 util.getLocalReplicationServerName() +
339
                                 "&docid=" + docid);
340

    
341
              }//else
342
            }//else if
343
          }//else has implicit action
344

    
345
          //Make sure comeAndGetIt is not empty
346
          if ( comeAndGetIt != null && !comeAndGetIt.equals(""))
347
          {
348
            logMetacat.warn("sending message: "
349
                                                + comeAndGetIt.toString());
350
            String message = MetacatReplication.getURLContent(comeAndGetIt);
351
          }
352
          //send out the url.  message is a dummy variable as the target of
353
          //the URL never directly replies to the request.  this simply
354
          //invoces a read request from the server to this local machine.
355
         }//if notification server
356
        }
357
        catch (Exception ee)
358
        {
359
        	logMetacat.error("error in ForceReplicationHandler.run for server " 
360
                    + server +" "+ee.getMessage());
361
             ee.printStackTrace();
362
        }
363
      }//for
364

    
365
   
366
      logMetacat.warn("exiting ForceReplicationHandler Thread");
367
  }//run
368
}//ForceReplication class
(39-39/66)