Project

General

Profile

1 581 berkley
/**
2
 *  '$RCSfile$'
3 2298 tao
 *    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 669 jones
 *             with a certain docid.
8 581 berkley
 *  Copyright: 2000 Regents of the University of California and the
9
 *             National Center for Ecological Analysis and Synthesis
10 669 jones
 *    Authors: Chad Berkley
11 581 berkley
 *
12 669 jones
 *   '$Author$'
13
 *     '$Date$'
14
 * '$Revision$'
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 581 berkley
 */
30 2298 tao
31 5014 daigle
package edu.ucsb.nceas.metacat.replication;
32 581 berkley
33 5014 daigle
import java.io.IOException;
34 581 berkley
import java.net.*;
35
36 2663 sgarg
import org.apache.log4j.Logger;
37
38 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
39 5014 daigle
import edu.ucsb.nceas.metacat.shared.ServiceException;
40 4698 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
41 5014 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
42 4080 daigle
43 669 jones
/**
44 2298 tao
 * A class to asyncronously force the replication of each server
45
 * that has an entry in the xml_replication table.  When run,
46
 * this thread communicates with each server in the list and
47
 * solicites a read of an updated or newly inserted document
48 669 jones
 * with a certain docid.
49
 */
50 581 berkley
public class ForceReplicationHandler implements Runnable
51
{
52
  private Thread btThread;
53
  private String docid;
54
  private String action;
55 1022 tao
  private boolean xmlDocument;
56 581 berkley
  private boolean dbactionFlag = true;
57 2298 tao
  private ReplicationServerList serverLists = null;//Serverlist
58 1292 tao
  private int homeServerCode = 0; // home server code for the docid
59 2298 tao
  // When a metacat A got forcereplication
60 1292 tao
  // 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 5014 daigle
  private static Logger logReplication = Logger.getLogger("ReplicationLogging");
65
  private static Logger logMetacat = Logger.getLogger(ForceReplicationHandler.class);
66 2298 tao
67
  //constant
68
  public static final String DELETE = "delete";
69
70
71
72 581 berkley
  /**
73 1292 tao
   * Constructor of ForceReplicationHandler
74 581 berkley
   * @param docid the docid to force replicate
75 2298 tao
   * @param the action that is being performed on the document (either
76 581 berkley
   *        INSERT or UPDATE)
77 1292 tao
   * @param xml the docid is a xml document or not (data file)
78 2298 tao
   * @param notificationServer, when a metacat A got forcereplication
79 1292 tao
   * notification from B, then A will update its record. And A will notification
80
   * other metacat in its serverlist to update this docid if A is a hub. But we
81
   * don't want A to notify B again. B is nofitification of A.
82 581 berkley
   */
83 2298 tao
  public ForceReplicationHandler(String docid, String action, boolean xml,
84 3230 tao
                                                   String myNotificationServer)
85 581 berkley
  {
86
    this.docid = docid;
87
    this.action = action;
88 1022 tao
    this.xmlDocument =xml;
89 1292 tao
    // Build a severLists from xml_replication table
90
    this.serverLists = new ReplicationServerList();
91
    // Get sever code for this docid
92
    try
93
    {
94 5014 daigle
      this.homeServerCode = ReplicationService.getHomeServerCodeForDocId(docid);
95 1292 tao
    }//try
96 5014 daigle
    catch (ServiceException se)
97 1292 tao
    {
98 5014 daigle
    	logMetacat.error("ForceReplicationHandler() - " + ReplicationService.METACAT_REPL_ERROR_MSG);
99
    	logReplication.error("ForceReplicationHandler() - Service issue in constructor: "
100
    			+ se.getMessage());
101 1292 tao
    }//catch
102
    // Get the notification server
103
    this.notificationServer = myNotificationServer;
104 2298 tao
105 581 berkley
    if(this.action.equals(""))
106
    {
107
      dbactionFlag = false;
108
    }
109 2298 tao
110 581 berkley
    btThread = new Thread(this);
111
    btThread.setPriority(Thread.MIN_PRIORITY);
112
    btThread.start();
113
  }
114 2298 tao
115 581 berkley
  /**
116
   * Use this constructor when the action is implied.
117
   */
118 2298 tao
  public ForceReplicationHandler(String docid, boolean xml,
119 3230 tao
                                                String myNotificationServer )
120 581 berkley
  {
121
    this.docid = docid;
122 1022 tao
    this.xmlDocument = xml;
123 581 berkley
    dbactionFlag = false;
124 1292 tao
    // Build a severLists from xml_replication table
125
    this.serverLists = new ReplicationServerList();
126
    // Get home server code for this doicd
127
    try
128
    {
129 5014 daigle
      this.homeServerCode = ReplicationService.getHomeServerCodeForDocId(docid);
130 1292 tao
    }
131 5014 daigle
     catch (ServiceException se)
132 1292 tao
    {
133 5014 daigle
      logMetacat.error("ForceReplicationHandler() - " + ReplicationService.METACAT_REPL_ERROR_MSG);
134
      logReplication.error("ForceReplicationHandler()- Service issue in constructor: "
135
    			+ se.getMessage());
136 1292 tao
    }//catch
137
    // Get notification server
138
    this.notificationServer = myNotificationServer;
139 581 berkley
    btThread = new Thread(this);
140
    btThread.setPriority(Thread.MIN_PRIORITY);
141
    btThread.start();
142
  }
143 2298 tao
144 1292 tao
  /**
145 2298 tao
   * Method to send force replication command to other server to get
146 1292 tao
   * a new or updated docid
147
   */
148 581 berkley
  public void run()
149
  {
150 2298 tao
151 2649 tao
152 4080 daigle
	    // URL for notifcation
153
	    URL comeAndGetIt = null;
154
		// If no server in xml_replication table, metacat don't need do anything
155
		if (serverLists.isEmpty()) {
156
			return;
157
		}
158 2298 tao
159 4080 daigle
		// Thread seelping for some seconds to make sure the document was insert
160
		// into the database before we send force replication request
161
		int sleepTime;
162
		try {
163 5014 daigle
			sleepTime = Integer.parseInt(PropertyService.getProperty("replication.forcereplicationwaitingtime"));
164 4080 daigle
			Thread.sleep(sleepTime);
165 5014 daigle
		} catch (PropertyNotFoundException pnfe) {
166
	    	logMetacat.error("ForceReplicationHandler.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
167
			logReplication.error("ForceReplicationHandler.run - property error: " + pnfe.getMessage());
168
		} catch (InterruptedException ie) {
169
	    	logMetacat.error("ForceReplicationHandler.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
170
			logReplication.error("ForceReplicationHandler.run - Thread sleep error: " + ie.getMessage());
171 4080 daigle
		}
172 5014 daigle
		logReplication.info("ForceReplicationHandler.run - notification server:" + notificationServer);
173 4080 daigle
		// Check every server in the serverlists
174
		for (int i = 0; i < serverLists.size(); i++) {
175
			//Set comeAndGetIt null
176
			comeAndGetIt = null;
177
			// Get ReplicationServer object in index i
178
			ReplicationServer replicationServer = serverLists.serverAt(i);
179
			// Get this ReplicationServer 's name
180
			String server = replicationServer.getServerName();
181
			try {
182 2298 tao
183 4080 daigle
				// 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 2298 tao
187 4080 daigle
					if (dbactionFlag) {
188
						// xml documents and server can replicate xml doucment
189
						if (xmlDocument && replicationServer.getReplication()) {
190
							// If this docid's homeserver is localhost, replicate it
191
							if (homeServerCode == 1) {
192 5014 daigle
								logReplication.info("ForceReplicationHandler.run - force xml replicating to "
193 4080 daigle
										+ server);
194
								comeAndGetIt = new URL("https://" + server
195
										+ "?action=forcereplicate&server="
196 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
197 4080 daigle
										+ "&docid=" + docid + "&dbaction=" + action);
198
								//over write the url for delete
199
								if (action != null && action.equals(DELETE)) {
200
									comeAndGetIt = new URL("https://" + server
201
											+ "?action="
202 5014 daigle
											+ ReplicationService.FORCEREPLICATEDELETE
203 4080 daigle
											+ "&docid=" + docid + "&server="
204 4698 daigle
											+ MetacatUtil.getLocalReplicationServerName());
205 2298 tao
206 4080 daigle
								}
207
							}//if servercode==1
208
							else if (replicationServer.getHub()
209 5014 daigle
									|| server.equals(ReplicationService
210 4080 daigle
											.getServerNameForServerCode(homeServerCode))) {
211
								// If the docid's home server is not local host, but local host
212
								// is a hub of this server, replicate the docid too.
213
								// If the server is homeserver of the docid, replication it too
214 5014 daigle
								logReplication.info("ForceReplicationHandler.run - force xml replicating to "
215 4080 daigle
										+ server);
216
								comeAndGetIt = new URL("https://" + server
217
										+ "?action=forcereplicate&server="
218 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
219 4080 daigle
										+ "&docid=" + docid + "&dbaction=" + action);
220
								//over write the url for delete
221
								if (action != null && action.equals(DELETE)) {
222
									comeAndGetIt = new URL("https://" + server
223
											+ "?action="
224 5014 daigle
											+ ReplicationService.FORCEREPLICATEDELETE
225 4080 daigle
											+ "&docid=" + docid + "&server="
226 4698 daigle
											+ MetacatUtil.getLocalReplicationServerName());
227 2298 tao
228 4080 daigle
								}
229
							}//else
230 2298 tao
231 4080 daigle
						}//if xmlDocument
232
						//It is data file and configured to handle data replication
233
						else if (replicationServer.getDataReplication()) {
234
							// If the docid's home server is local host, replicate the docid
235
							if (homeServerCode == 1) {
236 5014 daigle
								logReplication.info("ForceReplicationHandler.run - force data replicating to "
237 4080 daigle
										+ server);
238
								comeAndGetIt = new URL("https://" + server
239
										+ "?action=forcereplicatedatafile&server="
240 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
241 4080 daigle
										+ "&docid=" + docid + "&dbaction=" + action);
242
								//over write the url for delete
243
								if (action != null && action.equals(DELETE)) {
244
									comeAndGetIt = new URL("https://" + server
245
											+ "?action="
246 5014 daigle
											+ ReplicationService.FORCEREPLICATEDELETE
247 4080 daigle
											+ "&docid=" + docid + "&server="
248 4698 daigle
											+ MetacatUtil.getLocalReplicationServerName());
249 2298 tao
250 4080 daigle
								}
251 2298 tao
252 4080 daigle
							}//if serverCode==1
253
							else if (replicationServer.getHub()
254 5014 daigle
									|| server.equals(ReplicationService
255 4080 daigle
											.getServerNameForServerCode(homeServerCode))) {
256
								// If the docid's home server is not local host, but local host
257
								// is a hub of this server, replicate the docid too.
258
								// If the server is homeserver of the docid replication it too
259 5014 daigle
								logReplication.info("ForceReplicationHandler.run - force data replicating to "
260 4080 daigle
										+ server);
261
								comeAndGetIt = new URL("https://" + server
262
										+ "?action=forcereplicatedatafile&server="
263 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
264 4080 daigle
										+ "&docid=" + docid + "&dbaction=" + action);
265
								//over write the url for delete
266
								if (action != null && action.equals(DELETE)) {
267
									comeAndGetIt = new URL("https://" + server
268
											+ "?action="
269 5014 daigle
											+ ReplicationService.FORCEREPLICATEDELETE
270 4080 daigle
											+ "&docid=" + docid + "&server="
271 4698 daigle
											+ MetacatUtil.getLocalReplicationServerName());
272 2298 tao
273 4080 daigle
								}
274 2298 tao
275 4080 daigle
							}//else if servercode==1
276
						}//else if data file
277 2298 tao
278 4080 daigle
					}//if has explicite action
279
					else { // has implicite action
280 5014 daigle
						logReplication.info("ForceReplicationHandler.run - force replicating (default action) to )"
281 4080 daigle
										+ server);
282
						// this docid is xml documents and can replicate xml doucment
283
						if (xmlDocument && replicationServer.getReplication()) {
284
							// If homeserver of this doicd is local, replicate it
285
							if (homeServerCode == 1) {
286
								comeAndGetIt = new URL("https://" + server
287
										+ "?action=forcereplicate&server="
288 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
289 4080 daigle
										+ "&docid=" + docid);
290 2298 tao
291 4080 daigle
							}//if homeserver ==1
292
							else if (replicationServer.getHub()
293 5014 daigle
									|| server.equals(ReplicationService
294 4080 daigle
											.getServerNameForServerCode(homeServerCode))) {
295
								// If home server of this docid is not local host, but local
296
								// host is a hub for this server, replicate this doicd
297
								// If the server is homeserver of the docid, replication it too
298
								comeAndGetIt = new URL("https://" + server
299
										+ "?action=forcereplicate&server="
300 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
301 4080 daigle
										+ "&docid=" + docid);
302 2298 tao
303 4080 daigle
							}//else if
304 2298 tao
305 4080 daigle
						}//if xmlDoucment
306
						else if (replicationServer.getDataReplication()) { //It is datafile and server is configured to replicate data file
307 2298 tao
308 4080 daigle
							//if home server is local host, replicate the data file
309
							if (homeServerCode == 1) {
310
								comeAndGetIt = new URL("https://" + server
311
										+ "?action=forcereplicatedatafile&server="
312 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
313 4080 daigle
										+ "&docid=" + docid);
314
							}//if
315
							else if (replicationServer.getHub()
316 5014 daigle
									|| server.equals(ReplicationService
317 4080 daigle
											.getServerNameForServerCode(homeServerCode))) {
318
								// If home server is not local host, but the local host is a hub
319
								// For this server, replicate the data file
320
								// If the server is homeserver of the docid, replication it too
321
								comeAndGetIt = new URL("https://" + server
322
										+ "?action=forcereplicatedatafile&server="
323 4698 daigle
										+ MetacatUtil.getLocalReplicationServerName()
324 4080 daigle
										+ "&docid=" + docid);
325 2298 tao
326 4080 daigle
							}//else
327
						}//else if
328
					}//else has implicit action
329 2298 tao
330 4080 daigle
					//Make sure comeAndGetIt is not empty
331
					if (comeAndGetIt != null && !comeAndGetIt.equals("")) {
332 5014 daigle
						logReplication.warn("ForceReplicationHandler.run - sending message: " + comeAndGetIt.toString());
333
						String message = ReplicationService.getURLContent(comeAndGetIt);
334 4080 daigle
					}
335
					//send out the url.  message is a dummy variable as the target of
336
					//the URL never directly replies to the request.  this simply
337
					//invoces a read request from the server to this local machine.
338
				}//if notification server
339 5014 daigle
			} catch (MalformedURLException mue) {
340
		    	logMetacat.error("ForceReplicationHandler.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
341
				logReplication.error("ForceReplicationHandler.run - URL error in ForceReplicationHandler.run for server "
342
						+ server + " : " + mue.getMessage());
343
//				mue.printStackTrace();
344
			} catch (IOException io) {
345
		    	logMetacat.error("ForceReplicationHandler.run - " + ReplicationService.METACAT_REPL_ERROR_MSG);
346
				logReplication.error("ForceReplicationHandler.run - I/O error in ForceReplicationHandler.run for server "
347
						+ server + " : " + io.getMessage());
348 4080 daigle
			}
349
		}//for
350 2298 tao
351 5014 daigle
		logReplication.warn("ForceReplicationHandler.run - exiting ForceReplicationHandler Thread");
352 4080 daigle
	}//run
353 1292 tao
}//ForceReplication class