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: daigle $'
13
 *     '$Date: 2008-07-29 11:32:31 -0700 (Tue, 29 Jul 2008) $'
14
 * '$Revision: 4178 $'
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
import edu.ucsb.nceas.metacat.service.PropertyService;
43
import edu.ucsb.nceas.metacat.util.MetaCatUtil;
44

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

    
68
  //constant
69
  public static final String DELETE = "delete";
70

    
71

    
72

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

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

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

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

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

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

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

    
179
				// If the server is the notification server, we don't notify it back
180
				// again, if server is null we don't replication it
181
				if (server != null && !server.equals(notificationServer)) {
182

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

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

    
224
								}
225
							}//else
226

    
227
						}//if xmlDocument
228
						//It is data file and configured to handle data replication
229
						else if (replicationServer.getDataReplication()) {
230
							// If the docid's home server is local host, replicate the docid
231
							if (homeServerCode == 1) {
232
								MetacatReplication.replLog("force data replicating to "
233
										+ server);
234
								comeAndGetIt = new URL("https://" + server
235
										+ "?action=forcereplicatedatafile&server="
236
										+ MetaCatUtil.getLocalReplicationServerName()
237
										+ "&docid=" + docid + "&dbaction=" + action);
238
								//over write the url for delete
239
								if (action != null && action.equals(DELETE)) {
240
									comeAndGetIt = new URL("https://" + server
241
											+ "?action="
242
											+ MetacatReplication.FORCEREPLICATEDELETE
243
											+ "&docid=" + docid + "&server="
244
											+ MetaCatUtil.getLocalReplicationServerName());
245

    
246
								}
247

    
248
							}//if serverCode==1
249
							else if (replicationServer.getHub()
250
									|| server.equals(MetacatReplication
251
											.getServerNameForServerCode(homeServerCode))) {
252
								// If the docid's home server is not local host, but local host
253
								// is a hub of this server, replicate the docid too.
254
								// If the server is homeserver of the docid replication it too
255
								MetacatReplication.replLog("force data replicating to "
256
										+ server);
257
								comeAndGetIt = new URL("https://" + server
258
										+ "?action=forcereplicatedatafile&server="
259
										+ MetaCatUtil.getLocalReplicationServerName()
260
										+ "&docid=" + docid + "&dbaction=" + action);
261
								//over write the url for delete
262
								if (action != null && action.equals(DELETE)) {
263
									comeAndGetIt = new URL("https://" + server
264
											+ "?action="
265
											+ MetacatReplication.FORCEREPLICATEDELETE
266
											+ "&docid=" + docid + "&server="
267
											+ MetaCatUtil.getLocalReplicationServerName());
268

    
269
								}
270

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

    
274
					}//if has explicite action
275
					else { // has implicite action
276
						MetacatReplication
277
								.replLog("force replicating (default action) to )"
278
										+ server);
279
						// this docid is xml documents and can replicate xml doucment
280
						if (xmlDocument && replicationServer.getReplication()) {
281
							// If homeserver of this doicd is local, replicate it
282
							if (homeServerCode == 1) {
283
								comeAndGetIt = new URL("https://" + server
284
										+ "?action=forcereplicate&server="
285
										+ MetaCatUtil.getLocalReplicationServerName()
286
										+ "&docid=" + docid);
287

    
288
							}//if homeserver ==1
289
							else if (replicationServer.getHub()
290
									|| server.equals(MetacatReplication
291
											.getServerNameForServerCode(homeServerCode))) {
292
								// If home server of this docid is not local host, but local
293
								// host is a hub for this server, replicate this doicd
294
								// If the server is homeserver of the docid, replication it too
295
								comeAndGetIt = new URL("https://" + server
296
										+ "?action=forcereplicate&server="
297
										+ MetaCatUtil.getLocalReplicationServerName()
298
										+ "&docid=" + docid);
299

    
300
							}//else if
301

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

    
305
							//if home server is local host, replicate the data file
306
							if (homeServerCode == 1) {
307
								comeAndGetIt = new URL("https://" + server
308
										+ "?action=forcereplicatedatafile&server="
309
										+ MetaCatUtil.getLocalReplicationServerName()
310
										+ "&docid=" + docid);
311
							}//if
312
							else if (replicationServer.getHub()
313
									|| server.equals(MetacatReplication
314
											.getServerNameForServerCode(homeServerCode))) {
315
								// If home server is not local host, but the local host is a hub
316
								// For this server, replicate the data file
317
								// If the server is homeserver of the docid, replication it too
318
								comeAndGetIt = new URL("https://" + server
319
										+ "?action=forcereplicatedatafile&server="
320
										+ MetaCatUtil.getLocalReplicationServerName()
321
										+ "&docid=" + docid);
322

    
323
							}//else
324
						}//else if
325
					}//else has implicit action
326

    
327
					//Make sure comeAndGetIt is not empty
328
					if (comeAndGetIt != null && !comeAndGetIt.equals("")) {
329
						logMetacat.warn("sending message: " + comeAndGetIt.toString());
330
						String message = MetacatReplication.getURLContent(comeAndGetIt);
331
					}
332
					//send out the url.  message is a dummy variable as the target of
333
					//the URL never directly replies to the request.  this simply
334
					//invoces a read request from the server to this local machine.
335
				}//if notification server
336
			} catch (Exception ee) {
337
				logMetacat.error("error in ForceReplicationHandler.run for server "
338
						+ server + " " + ee.getMessage());
339
				ee.printStackTrace();
340
			}
341
		}//for
342

    
343
		logMetacat.warn("exiting ForceReplicationHandler Thread");
344
	}//run
345
}//ForceReplication class
(40-40/68)