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: leinfelder $'
13
 *     '$Date: 2013-07-02 16:47:11 -0700 (Tue, 02 Jul 2013) $'
14
 * '$Revision: 7840 $'
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.replication;
32

    
33
import java.io.IOException;
34
import java.net.*;
35

    
36
import org.apache.log4j.Logger;
37

    
38
import edu.ucsb.nceas.metacat.properties.PropertyService;
39
import edu.ucsb.nceas.metacat.shared.ServiceException;
40
import edu.ucsb.nceas.metacat.util.MetacatUtil;
41
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
42

    
43
/**
44
 * 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
 * with a certain docid.
49
 */
50
public class ForceReplicationHandler implements Runnable
51
{
52
  private Thread btThread;
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 static Logger logReplication = Logger.getLogger("ReplicationLogging");
65
  private static Logger logMetacat = Logger.getLogger(ForceReplicationHandler.class);
66

    
67
  /**
68
   * Constructor of ForceReplicationHandler
69
   * @param docid the docid to force replicate
70
   * @param the action that is being performed on the document (either
71
   *        INSERT or UPDATE)
72
   * @param xml the docid is a xml document or not (data file)
73
   * @param notificationServer, when a metacat A got forcereplication
74
   * 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
   */
78
  public ForceReplicationHandler(String docid, String action, boolean xml,
79
                                                   String myNotificationServer)
80
  {
81
    this.docid = docid;
82
    this.action = action;
83
    this.xmlDocument =xml;
84
    // Build a severLists from xml_replication table
85
    this.serverLists = new ReplicationServerList();
86
    // Get sever code for this docid
87
    try
88
    {
89
      this.homeServerCode = ReplicationService.getHomeServerCodeForDocId(docid);
90
    }//try
91
    catch (ServiceException se)
92
    {
93
    	logMetacat.error("ForceReplicationHandler() - " + ReplicationService.METACAT_REPL_ERROR_MSG);
94
    	logReplication.error("ForceReplicationHandler() - Service issue in constructor: " 
95
    			+ se.getMessage());
96
    }//catch
97
    // Get the notification server
98
    this.notificationServer = myNotificationServer;
99

    
100
    if(this.action.equals(""))
101
    {
102
      dbactionFlag = false;
103
    }
104

    
105
    btThread = new Thread(this);
106
    btThread.setPriority(Thread.MIN_PRIORITY);
107
    btThread.start();
108
  }
109

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

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

    
146
    
147
	    // 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

    
154
		// 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
			sleepTime = Integer.parseInt(PropertyService.getProperty("replication.forcereplicationwaitingtime"));
159
			Thread.sleep(sleepTime);
160
		} 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
		}
167
		logReplication.info("ForceReplicationHandler.run - notification server:" + notificationServer);
168
		// 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

    
178
				// 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

    
182
					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
								logReplication.info("ForceReplicationHandler.run - force xml replicating to "
188
										+ server);
189
								comeAndGetIt = new URL("https://" + server
190
										+ "?action=forcereplicate&server="
191
										+ MetacatUtil.getLocalReplicationServerName()
192
										+ "&docid=" + docid + "&dbaction=" + action);
193
								//over write the url for delete
194
								if (action != null && (action.equals(ReplicationService.FORCEREPLICATEDELETE) || action.equals(ReplicationService.FORCEREPLICATEDELETEALL))) {
195
									comeAndGetIt = new URL("https://" + server
196
											+ "?action="
197
											+ action
198
											+ "&docid=" + docid + "&server="
199
											+ MetacatUtil.getLocalReplicationServerName());
200

    
201
								}
202
							}//if servercode==1
203
							else if (replicationServer.getHub()
204
									|| server.equals(ReplicationService
205
											.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
								logReplication.info("ForceReplicationHandler.run - force xml replicating to "
210
										+ server);
211
								comeAndGetIt = new URL("https://" + server
212
										+ "?action=forcereplicate&server="
213
										+ MetacatUtil.getLocalReplicationServerName()
214
										+ "&docid=" + docid + "&dbaction=" + action);
215
								//over write the url for delete
216
								if (action != null && (action.equals(ReplicationService.FORCEREPLICATEDELETE) || action.equals(ReplicationService.FORCEREPLICATEDELETEALL))) {
217
									comeAndGetIt = new URL("https://" + server
218
											+ "?action="
219
											+ action
220
											+ "&docid=" + docid + "&server="
221
											+ MetacatUtil.getLocalReplicationServerName());
222

    
223
								}
224
							}//else
225

    
226
						}//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
								logReplication.info("ForceReplicationHandler.run - force data replicating to "
232
										+ server);
233
								comeAndGetIt = new URL("https://" + server
234
										+ "?action=forcereplicatedatafile&server="
235
										+ MetacatUtil.getLocalReplicationServerName()
236
										+ "&docid=" + docid + "&dbaction=" + action);
237
								//over write the url for delete
238
								if (action != null && (action.equals(ReplicationService.FORCEREPLICATEDELETE) || action.equals(ReplicationService.FORCEREPLICATEDELETEALL))) {
239
									comeAndGetIt = new URL("https://" + server
240
											+ "?action="
241
											+ action
242
											+ "&docid=" + docid + "&server="
243
											+ MetacatUtil.getLocalReplicationServerName());
244

    
245
								}
246

    
247
							}//if serverCode==1
248
							else if (replicationServer.getHub()
249
									|| server.equals(ReplicationService
250
											.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
								logReplication.info("ForceReplicationHandler.run - force data replicating to "
255
										+ server);
256
								comeAndGetIt = new URL("https://" + server
257
										+ "?action=forcereplicatedatafile&server="
258
										+ MetacatUtil.getLocalReplicationServerName()
259
										+ "&docid=" + docid + "&dbaction=" + action);
260
								//over write the url for delete
261
								if (action != null && (action.equals(ReplicationService.FORCEREPLICATEDELETE) || action.equals(ReplicationService.FORCEREPLICATEDELETEALL))) {
262
									comeAndGetIt = new URL("https://" + server
263
											+ "?action="
264
											+ action
265
											+ "&docid=" + docid + "&server="
266
											+ MetacatUtil.getLocalReplicationServerName());
267

    
268
								}
269

    
270
							}//else if servercode==1
271
						}//else if data file
272

    
273
					}//if has explicite action
274
					else { // has implicite action
275
						logReplication.info("ForceReplicationHandler.run - force replicating (default action) to )"
276
										+ 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
										+ MetacatUtil.getLocalReplicationServerName()
284
										+ "&docid=" + docid);
285

    
286
							}//if homeserver ==1
287
							else if (replicationServer.getHub()
288
									|| server.equals(ReplicationService
289
											.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
										+ MetacatUtil.getLocalReplicationServerName()
296
										+ "&docid=" + docid);
297

    
298
							}//else if
299

    
300
						}//if xmlDoucment
301
						else if (replicationServer.getDataReplication()) { //It is datafile and server is configured to replicate data file
302

    
303
							//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
										+ MetacatUtil.getLocalReplicationServerName()
308
										+ "&docid=" + docid);
309
							}//if
310
							else if (replicationServer.getHub()
311
									|| server.equals(ReplicationService
312
											.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
										+ MetacatUtil.getLocalReplicationServerName()
319
										+ "&docid=" + docid);
320

    
321
							}//else
322
						}//else if
323
					}//else has implicit action
324

    
325
					//Make sure comeAndGetIt is not empty
326
					if (comeAndGetIt != null && !comeAndGetIt.equals("")) {
327
						logReplication.warn("ForceReplicationHandler.run - sending message: " + comeAndGetIt.toString());
328
						String message = ReplicationService.getURLContent(comeAndGetIt);
329
					}
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
			} 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
			}
344
		}//for
345

    
346
		logReplication.warn("ForceReplicationHandler.run - exiting ForceReplicationHandler Thread");
347
	}//run
348
}//ForceReplication class
(1-1/7)