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