~ubuntu-branches/ubuntu/raring/libjboss-remoting-java/raring

« back to all changes in this revision

Viewing changes to src/org/jboss/remoting/ConnectionValidator.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
* JBoss, Home of Professional Open Source
3
 
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
 
* by the @authors tag. See the copyright.txt in the distribution for a
5
 
* full listing of individual contributors.
6
 
*
7
 
* This is free software; you can redistribute it and/or modify it
8
 
* under the terms of the GNU Lesser General Public License as
9
 
* published by the Free Software Foundation; either version 2.1 of
10
 
* the License, or (at your option) any later version.
11
 
*
12
 
* This software is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 
* Lesser General Public License for more details.
16
 
*
17
 
* You should have received a copy of the GNU Lesser General Public
18
 
* License along with this software; if not, write to the Free
19
 
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
 
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21
 
*/
22
 
 
23
 
package org.jboss.remoting;
24
 
 
25
 
import java.util.HashMap;
26
 
import java.util.HashSet;
27
 
import java.util.Iterator;
28
 
import java.util.Map;
29
 
import java.util.Set;
30
 
import java.util.Timer;
31
 
import java.util.TimerTask;
32
 
 
33
 
import org.jboss.logging.Logger;
34
 
import org.jboss.remoting.transport.ClientInvoker;
35
 
import org.jboss.remoting.util.StoppableTimerTask;
36
 
import org.jboss.remoting.util.TimerUtil;
37
 
 
38
 
/**
39
 
 * @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
40
 
 * @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
41
 
 * @author <a href="mailto:tlee@redhat.com">Trustin Lee</a>
42
 
 */
43
 
public class ConnectionValidator extends TimerTask implements StoppableTimerTask
44
 
{
45
 
   // Constants ------------------------------------------------------------------------------------
46
 
 
47
 
   private static final Logger log = Logger.getLogger(ConnectionValidator.class.getName());
48
 
 
49
 
   /** Configuration map key for ping period. */
50
 
   public static final String VALIDATOR_PING_PERIOD = "validatorPingPeriod";
51
 
   
52
 
   /** Default ping period. Value is 2 seconds. */
53
 
   public static final long DEFAULT_PING_PERIOD = 2000;
54
 
   
55
 
   /** Configuration map key for ping timeout. */
56
 
   public static final String VALIDATOR_PING_TIMEOUT = "validatorPingTimeout";
57
 
   
58
 
   /** Default ping timeout period.  Value is 1 second. */
59
 
   public static final String DEFAULT_PING_TIMEOUT = "1000";
60
 
 
61
 
   /** Default ping timeout period.  Value is 1 second. */
62
 
   public static final int DEFAULT_PING_TIMEOUT_INT = 1000;
63
 
   
64
 
   /**
65
 
    * Default number of ping retries.  Value is 1.
66
 
    * Currently implemented only on socket transport family.
67
 
    */
68
 
   public static final String DEFAULT_NUMBER_OF_PING_RETRIES = "1";
69
 
 
70
 
   /**
71
 
    * Key to determine if ConnectionValidator should tie failure to presence
72
 
    * of active lease on server side.  Default value is "true".
73
 
    */
74
 
   public static final String TIE_TO_LEASE = "tieToLease";
75
 
   
76
 
   /**
77
 
    * Key to determine whether to stop ConnectionValidator when PING fails.
78
 
    * Default value is "true".
79
 
    */
80
 
   public static final String STOP_LEASE_ON_FAILURE = "stopLeaseOnFailure";
81
 
   
82
 
   /**
83
 
    * Key to determine value of disconnectTimeout upon connection failure.
84
 
    */
85
 
   public static final String FAILURE_DISCONNECT_TIMEOUT = "failureDisconnectTimeout";
86
 
   
87
 
   // Static ---------------------------------------------------------------------------------------
88
 
 
89
 
   private static boolean trace = log.isTraceEnabled();
90
 
 
91
 
   /**
92
 
    * Will make $PING$ invocation on server. If sucessful, will return true. Otherwise, will throw
93
 
    * an exception.
94
 
    *
95
 
    * @param locator - locator for the server to ping
96
 
    * @param config  - any configuration needed for server
97
 
    * @return true if alive, false if not
98
 
    */
99
 
   public static boolean checkConnection(InvokerLocator locator, Map config) throws Throwable
100
 
   {
101
 
      boolean pingWorked = false;
102
 
      Map configMap = createPingConfig(config, null);
103
 
      int pingTimeout = Integer.parseInt((String) configMap.get(ServerInvoker.TIMEOUT));
104
 
      ClientInvoker innerClientInvoker = null;
105
 
 
106
 
      try
107
 
      {
108
 
         innerClientInvoker = InvokerRegistry.createClientInvoker(locator, configMap);
109
 
 
110
 
         if (!innerClientInvoker.isConnected())
111
 
         {
112
 
            if (trace) { log.trace("inner client invoker not connected, connecting ..."); }
113
 
            innerClientInvoker.connect();
114
 
         }
115
 
 
116
 
         pingWorked = doCheckConnection(innerClientInvoker, pingTimeout);
117
 
      }
118
 
      catch (Throwable throwable)
119
 
      {
120
 
         log.debug("ConnectionValidator unable to connect to server " +
121
 
            innerClientInvoker.getLocator().getProtocol() + "://" +
122
 
            innerClientInvoker.getLocator().getHost() + ":" +
123
 
            innerClientInvoker.getLocator().getPort(), throwable);
124
 
      }
125
 
      finally
126
 
      {
127
 
         if (innerClientInvoker != null)
128
 
         {
129
 
            InvokerRegistry.destroyClientInvoker(locator, configMap);
130
 
         }
131
 
      }
132
 
 
133
 
      return pingWorked;
134
 
   }
135
 
 
136
 
   private static boolean doCheckConnection(ClientInvoker clientInvoker, int pingTimeout) throws Throwable
137
 
   {
138
 
      boolean pingWorked = false;
139
 
 
140
 
      try
141
 
      {
142
 
         // Sending null client id as don't want to trigger lease on server side. This also means
143
 
         // that client connection validator will NOT impact client lease, so can not depend on it
144
 
         // to maintain client lease with the server.
145
 
         InvocationRequest ir;
146
 
         ir = new InvocationRequest(null, Subsystem.SELF, "$PING$", null, null, null);
147
 
         ConnectionCheckThread t = new ConnectionCheckThread(clientInvoker, ir);
148
 
         t.start();
149
 
         Thread.sleep(pingTimeout);
150
 
         pingWorked = t.isValid();
151
 
      }
152
 
      catch (Throwable t)
153
 
      {
154
 
         log.debug("ConnectionValidator failed to ping via " + clientInvoker, t);
155
 
      }
156
 
 
157
 
      return pingWorked;
158
 
   }
159
 
   
160
 
   private static Map createPingConfig(Map config, Map metadata)
161
 
   {
162
 
      Map localConfig = new HashMap();
163
 
      localConfig.put("connection_checker", "true");
164
 
 
165
 
      if (config != null)
166
 
      {
167
 
         Object o = config.get(VALIDATOR_PING_TIMEOUT);
168
 
         log.trace("config timeout: " + o);
169
 
         if (o != null)
170
 
         {
171
 
            try
172
 
            {
173
 
               Integer.parseInt((String) o);
174
 
               localConfig.put(ServerInvoker.TIMEOUT, o);
175
 
            }
176
 
            catch (NumberFormatException e)
177
 
            {
178
 
               log.warn("Need integer for value of parameter " + VALIDATOR_PING_TIMEOUT + 
179
 
                        ". Using default value " + DEFAULT_PING_TIMEOUT);
180
 
            }
181
 
         }
182
 
         
183
 
         o = config.get("NumberOfCallRetries");
184
 
         if (o != null)
185
 
         {
186
 
            localConfig.put("NumberOfCallRetries", o);
187
 
         }
188
 
      }
189
 
      
190
 
      if (metadata != null)
191
 
      {
192
 
         metadata.remove(ServerInvoker.TIMEOUT);
193
 
         localConfig.putAll(metadata);
194
 
         Object o = metadata.get(VALIDATOR_PING_TIMEOUT);
195
 
         if (o != null)
196
 
         {
197
 
            try
198
 
            {
199
 
               Integer.parseInt((String) o);
200
 
               localConfig.put(ServerInvoker.TIMEOUT, o);
201
 
            }
202
 
            catch (NumberFormatException e)
203
 
            {
204
 
               log.warn("Need integer for value of parameter " + VALIDATOR_PING_TIMEOUT +
205
 
                        ". Using default value " + DEFAULT_PING_TIMEOUT);
206
 
            }
207
 
         }
208
 
      }
209
 
      
210
 
      if (localConfig.get(ServerInvoker.TIMEOUT) == null)
211
 
      {
212
 
         localConfig.put(ServerInvoker.TIMEOUT, DEFAULT_PING_TIMEOUT);
213
 
      }
214
 
      
215
 
      if (localConfig.get("NumberOfCallRetries") == null)
216
 
      {
217
 
         localConfig.put("NumberOfCallRetries", DEFAULT_NUMBER_OF_PING_RETRIES);
218
 
      }
219
 
      
220
 
      return localConfig;
221
 
   }
222
 
 
223
 
   // Attributes -----------------------------------------------------------------------------------
224
 
 
225
 
   private Client client;
226
 
   private long pingPeriod;
227
 
   private Map metadata;
228
 
   private InvokerLocator locator;
229
 
   private Map configMap;
230
 
   private Map listeners;
231
 
   private ClientInvoker clientInvoker;
232
 
   private Object lock = new Object();
233
 
   private Object notificationLock = new Object();
234
 
   private boolean started;
235
 
   private volatile boolean stopped;
236
 
   private volatile boolean stopping;
237
 
   private String invokerSessionId;
238
 
   private boolean tieToLease = true;
239
 
   private boolean stopLeaseOnFailure = true;
240
 
   private int pingTimeout;
241
 
   private int failureDisconnectTimeout = -1;
242
 
   private boolean isValid;
243
 
   private Timer timer;
244
 
   private MicroRemoteClientInvoker sharedInvoker;
245
 
   private LeasePinger leasePinger;
246
 
   private boolean useClientConnectionIdentity;
247
 
 
248
 
   // Constructors ---------------------------------------------------------------------------------
249
 
 
250
 
   public ConnectionValidator(Client client)
251
 
   {
252
 
      this(client, DEFAULT_PING_PERIOD);
253
 
   }
254
 
 
255
 
   public ConnectionValidator(Client client, long pingPeriod)
256
 
   {
257
 
      this.client = client;
258
 
      this.locator = client.getInvoker().getLocator();
259
 
      this.pingPeriod = pingPeriod;
260
 
      pingTimeout = DEFAULT_PING_TIMEOUT_INT;
261
 
      listeners = new HashMap();
262
 
      stopped = false;
263
 
      getParameters(client, new HashMap());
264
 
      log.debug(this + " created");
265
 
   }
266
 
   
267
 
   public ConnectionValidator(Client client, Map metadata)
268
 
   {
269
 
      this.client = client;
270
 
      this.locator = client.getInvoker().getLocator();
271
 
      pingPeriod = DEFAULT_PING_PERIOD;
272
 
      pingTimeout = DEFAULT_PING_TIMEOUT_INT;
273
 
      listeners = new HashMap();
274
 
      stopped = false;
275
 
      this.metadata = new HashMap(metadata);
276
 
      getParameters(client, metadata);
277
 
      log.debug(this + " created");
278
 
   }
279
 
 
280
 
   // StoppableTimerTask implementation ------------------------------------------------------------
281
 
 
282
 
   public void stop()
283
 
   {
284
 
      if (stopped)
285
 
      {
286
 
         return;
287
 
      }
288
 
 
289
 
      doStop();
290
 
   }
291
 
 
292
 
   // TimerTask overrides --------------------------------------------------------------------------
293
 
 
294
 
   /**
295
 
    * The action to be performed by this timer task.
296
 
    */
297
 
   public void run()
298
 
   {
299
 
      synchronized (lock)
300
 
      {
301
 
         if (!started)
302
 
         {
303
 
            throw new IllegalStateException(
304
 
                  ConnectionValidator.class.getName() + ".run() should not be " +
305
 
                  "called directly; use " + ConnectionValidator.class.getName() +
306
 
                  ".addConnectionListener() instead.");
307
 
         }
308
 
         
309
 
         if (stopping)
310
 
         {
311
 
            return;
312
 
         }
313
 
         
314
 
         TimerTask tt = new WaitOnConnectionCheckTimerTask();
315
 
 
316
 
         try
317
 
         {
318
 
            timer.schedule(tt, 0);
319
 
         }
320
 
         catch (IllegalStateException e)
321
 
         {
322
 
            log.debug("Unable to schedule TimerTask on existing Timer", e);
323
 
            timer = new Timer(true);
324
 
            timer.schedule(tt, 0);
325
 
         }
326
 
      }
327
 
 
328
 
      try
329
 
      {
330
 
         if(!stopping)
331
 
         {
332
 
            isValid = false;
333
 
 
334
 
            if (tieToLease && client.getLeasePeriod() > 0)
335
 
            {
336
 
               if (trace)
337
 
               {
338
 
                  log.trace(this + " sending PING tied to lease");
339
 
               }
340
 
               isValid = doCheckConnectionWithLease();
341
 
            }
342
 
            else
343
 
            {
344
 
               if (trace) { log.trace(this + " pinging ..."); }
345
 
               isValid = doCheckConnectionWithoutLease();
346
 
            }
347
 
         }
348
 
      }
349
 
      catch (Throwable thr)
350
 
      {
351
 
         log.debug(this + " got throwable while pinging", thr);
352
 
 
353
 
         if (stopLeaseOnFailure)
354
 
         {
355
 
            log.debug(this + " detected connection failure: stopping");
356
 
            cancel();
357
 
         }
358
 
      }
359
 
      finally
360
 
      {
361
 
         synchronized (notificationLock)
362
 
         {
363
 
            notificationLock.notifyAll();
364
 
         }
365
 
      }
366
 
   }
367
 
 
368
 
   public boolean cancel()
369
 
   {
370
 
      return doStop();
371
 
   }
372
 
 
373
 
   // Public ---------------------------------------------------------------------------------------
374
 
 
375
 
   public boolean addConnectionListener(Client client, ConnectionListener listener)
376
 
   {
377
 
      boolean doStart = false;
378
 
      if (listener != null)
379
 
      {
380
 
         synchronized (lock)
381
 
         {
382
 
            if (stopping)
383
 
            {
384
 
               if (trace) log.trace(this + " is stopped. Cannot add ConnectionListener: " + listener + " for " + client);
385
 
               return false;
386
 
            }
387
 
            if (listeners.size() == 0)
388
 
            {
389
 
               doStart = true;
390
 
            }
391
 
            Set s = (Set) listeners.get(listener);
392
 
            if (s == null)
393
 
            {
394
 
               s = new HashSet();
395
 
            }
396
 
            s.add(client);
397
 
            listeners.put(listener, s);
398
 
            log.debug(this + " added ConnectionListener: " + listener + " for " + client);
399
 
         }
400
 
         if (doStart)
401
 
         {
402
 
            start();
403
 
         }
404
 
      }
405
 
      
406
 
      return true;
407
 
   }
408
 
 
409
 
   public boolean removeConnectionListener(Client client, ConnectionListener listener)
410
 
   {
411
 
      if (listener == null)
412
 
      {
413
 
         if (trace) log.trace(this + " ConnectionListener is null");
414
 
         return false;
415
 
      }
416
 
      synchronized (lock)
417
 
      {
418
 
         if (stopping)
419
 
         {
420
 
            if (trace) log.trace(this + " is stopped. It's too late to remove " + listener);
421
 
            return false;
422
 
         }
423
 
         Set s = (Set) listeners.get(listener);
424
 
         if (s == null)
425
 
         {
426
 
            log.debug(this + ": " + listener + " is not registered");
427
 
            return false;
428
 
         }
429
 
         if (s.remove(client))
430
 
         {
431
 
            log.debug(this + " removed ConnectionListener: " + listener + " for " + client);
432
 
         }
433
 
         else
434
 
         {
435
 
            log.debug(this + ": " + listener + " is not registered for " + client);
436
 
            return false;
437
 
         }
438
 
         if (s.size() == 0)
439
 
         {
440
 
            listeners.remove(listener);
441
 
         }
442
 
         if (listeners.size() == 0)
443
 
         {
444
 
            stop();
445
 
         }
446
 
      }
447
 
      return true;
448
 
   }
449
 
 
450
 
   public long getPingPeriod()
451
 
   {
452
 
      if (stopping)
453
 
      {
454
 
         return -1;
455
 
      }
456
 
 
457
 
      return pingPeriod;
458
 
   }
459
 
 
460
 
   public String toString()
461
 
   {
462
 
      return "ConnectionValidator[" + Integer.toHexString(System.identityHashCode(this)) + ":" + clientInvoker + ", pingPeriod=" + pingPeriod + " ms]";
463
 
   }
464
 
   
465
 
   public boolean isStopped()
466
 
   {
467
 
      return stopped;
468
 
   }
469
 
 
470
 
   // Package protected ----------------------------------------------------------------------------
471
 
 
472
 
   void notifyListeners(Throwable thr)
473
 
   {
474
 
      final Throwable t = thr;
475
 
      synchronized (lock)
476
 
      {
477
 
         if (stopping)
478
 
         {
479
 
            return;
480
 
         }
481
 
         stopping = true;
482
 
         if (trace) log.trace(this + " is stopped.  No more listeners will be accepted.");
483
 
         
484
 
         Iterator itr = listeners.keySet().iterator();
485
 
         while (itr.hasNext())
486
 
         {
487
 
            final ConnectionListener listener = (ConnectionListener) itr.next();
488
 
            Set clients = (Set) listeners.get(listener);
489
 
            Iterator itr2 = clients.iterator();
490
 
            while (itr2.hasNext())
491
 
            {
492
 
               final Client client  = (Client) itr2.next();
493
 
               new Thread()
494
 
               {
495
 
                  public void run()
496
 
                  {
497
 
                     log.debug(ConnectionValidator.this + " calling " + listener + ".handleConnectionException() for " + client);
498
 
                     listener.handleConnectionException(t, client);
499
 
                  }
500
 
               }.start();
501
 
            }
502
 
         }
503
 
         
504
 
         listeners.clear();
505
 
      }
506
 
      
507
 
      stop();
508
 
   }
509
 
   
510
 
   // Protected ------------------------------------------------------------------------------------
511
 
 
512
 
   // Private --------------------------------------------------------------------------------------
513
 
 
514
 
   private void getParameters(Client client, Map metadata)
515
 
   {
516
 
      if (checkUseParametersFromLocator(client, metadata))
517
 
      {
518
 
         getParametersFromMap(client.getInvoker().getLocator().getParameters());
519
 
      }
520
 
      getParametersFromMap(client.getConfiguration());
521
 
      getParametersFromMap(metadata);
522
 
      
523
 
      ClientInvoker clientInvoker = client.getInvoker();
524
 
      if (clientInvoker instanceof MicroRemoteClientInvoker)
525
 
      {
526
 
         sharedInvoker = (MicroRemoteClientInvoker) clientInvoker;
527
 
         invokerSessionId = sharedInvoker.getSessionId();
528
 
      }
529
 
      else
530
 
      {
531
 
         throw new RuntimeException("creating a ConnectionValidator on a local connection");
532
 
      }
533
 
      if (stopLeaseOnFailure)
534
 
      {
535
 
         if (sharedInvoker != null)
536
 
         {
537
 
            leasePinger = sharedInvoker.getLeasePinger();
538
 
         }
539
 
      }
540
 
      if (trace) log.trace(this + ": sharedInvoker = " + sharedInvoker + ", leasePinger = " + leasePinger);
541
 
   }
542
 
   
543
 
   private boolean checkUseParametersFromLocator(Client client, Map metadata)
544
 
   {
545
 
      if (client.getInvoker() == null)
546
 
      {
547
 
         return false;
548
 
      }
549
 
      Object o = client.getInvoker().getLocator().getParameters().get(Client.USE_ALL_PARAMS);
550
 
      if (o != null)
551
 
      {
552
 
         if (o instanceof String)
553
 
         {
554
 
            return Boolean.valueOf(((String) o)).booleanValue();
555
 
         }
556
 
         else
557
 
         {
558
 
            log.warn(this + " could not convert " + Client.USE_ALL_PARAMS + " value" +
559
 
            " in InvokerLocator to a boolean: must be a String");
560
 
         }
561
 
      }
562
 
      o = client.getConfiguration().get(Client.USE_ALL_PARAMS);
563
 
      if (o != null)
564
 
      {
565
 
         if (o instanceof String)
566
 
         {
567
 
            return Boolean.valueOf(((String) o)).booleanValue();
568
 
         }
569
 
         else
570
 
         {
571
 
            log.warn(this + " could not convert " + Client.USE_ALL_PARAMS + " value" +
572
 
                     " in Client configuration map to a boolean: must be a String");
573
 
         }
574
 
      }
575
 
      o = metadata.get(Client.USE_ALL_PARAMS);
576
 
      if (o != null)
577
 
      {
578
 
         if (o instanceof String)
579
 
         {
580
 
            return Boolean.valueOf(((String) o)).booleanValue();
581
 
         }
582
 
         else
583
 
         {
584
 
            log.warn(this + " could not convert " + Client.USE_ALL_PARAMS + " value" +
585
 
                     " in metadata map to a boolean: must be a String");
586
 
         }
587
 
      }
588
 
      return false;
589
 
   }
590
 
   
591
 
   private void getParametersFromMap(Map config)
592
 
   {
593
 
      if (config != null)
594
 
      {  
595
 
         Object o = config.get(VALIDATOR_PING_PERIOD);
596
 
         if (o != null)
597
 
         {
598
 
            if (o instanceof String)
599
 
            {
600
 
               try 
601
 
               {
602
 
                  pingPeriod = Long.parseLong((String)o);
603
 
               }
604
 
               catch (Exception e)
605
 
               {
606
 
                  log.warn(this + " could not convert " + VALIDATOR_PING_PERIOD +
607
 
                           " value of " + o + " to a long value");
608
 
               }
609
 
            }
610
 
            else
611
 
            {
612
 
               log.warn(this + " could not convert " + VALIDATOR_PING_PERIOD +
613
 
                        " value of " + o + " to a long value: must be a String");
614
 
            }
615
 
         }
616
 
 
617
 
         o = config.get(VALIDATOR_PING_TIMEOUT);
618
 
         if (o != null)
619
 
         {
620
 
            if (o instanceof String)
621
 
            {
622
 
               try 
623
 
               {
624
 
                  pingTimeout = Integer.parseInt((String)o);
625
 
               }
626
 
               catch (Exception e)
627
 
               {
628
 
                  log.warn(this + " could not convert " + VALIDATOR_PING_TIMEOUT +
629
 
                           " value of " + o + " to a long value");
630
 
               }
631
 
            }
632
 
            else
633
 
            {
634
 
               log.warn(this + " could not convert " + VALIDATOR_PING_TIMEOUT +
635
 
                        " value of " + o + " to a long value: must be a String");
636
 
            }
637
 
         }
638
 
         
639
 
         o = config.get(TIE_TO_LEASE);
640
 
         if (o != null)
641
 
         {
642
 
            if (o instanceof String)
643
 
            {
644
 
               try
645
 
               {
646
 
                  tieToLease = Boolean.valueOf(((String) o)).booleanValue();
647
 
               }
648
 
               catch (Exception e)
649
 
               {
650
 
                  log.warn(this + " could not convert " + TIE_TO_LEASE + " value" +
651
 
                        " to a boolean: " + o);
652
 
               }
653
 
            }
654
 
            else
655
 
            {
656
 
               log.warn(this + " could not convert " + TIE_TO_LEASE + " value" +
657
 
               " to a boolean: must be a String");
658
 
            }
659
 
         }
660
 
 
661
 
         o = config.get(STOP_LEASE_ON_FAILURE);
662
 
         if (o != null)
663
 
         {
664
 
            if (o instanceof String)
665
 
            {
666
 
               try
667
 
               {
668
 
                  stopLeaseOnFailure = Boolean.valueOf(((String) o)).booleanValue();
669
 
               }
670
 
               catch (Exception e)
671
 
               {
672
 
                  log.warn(this + " could not convert " + STOP_LEASE_ON_FAILURE + " value" +
673
 
                        " to a boolean: " + o);
674
 
               }
675
 
            }
676
 
            else
677
 
            {
678
 
               log.warn(this + " could not convert " + STOP_LEASE_ON_FAILURE + " value" +
679
 
               " to a boolean: must be a String");
680
 
            }
681
 
         }
682
 
         
683
 
         o = config.get(FAILURE_DISCONNECT_TIMEOUT);
684
 
         if (trace) log.trace(this + " \"failureDisconnectTimeout\" set to " + o);
685
 
         if (o != null)
686
 
         {
687
 
            if (o instanceof String)
688
 
            {
689
 
               try
690
 
               {
691
 
                  failureDisconnectTimeout = Integer.valueOf(((String) o)).intValue();
692
 
                  if (trace) log.trace(this + " setting failureDisconnectTimeout to " + failureDisconnectTimeout);
693
 
               }
694
 
               catch (Exception e)
695
 
               {
696
 
                  log.warn(this + " could not convert " + FAILURE_DISCONNECT_TIMEOUT + " value" +
697
 
                        " to an int: " + o);
698
 
               }
699
 
            }
700
 
            else
701
 
            {
702
 
               log.warn(this + " could not convert " + FAILURE_DISCONNECT_TIMEOUT + " value" +
703
 
               " to an int: must be a String");
704
 
            }
705
 
         }
706
 
         o = config.get(Remoting.USE_CLIENT_CONNECTION_IDENTITY);
707
 
         if (o != null)
708
 
         {
709
 
            if (o instanceof String)
710
 
            {
711
 
               try
712
 
               {
713
 
                  useClientConnectionIdentity = Boolean.valueOf(((String) o)).booleanValue();
714
 
               }
715
 
               catch (Exception e)
716
 
               {
717
 
                  log.warn(this + " could not convert " + Remoting.USE_CLIENT_CONNECTION_IDENTITY + " value" +
718
 
                           " to a boolean: " + o);
719
 
               }
720
 
            }
721
 
            else
722
 
            {
723
 
               log.warn(this + " could not convert " + Remoting.USE_CLIENT_CONNECTION_IDENTITY + " value" +
724
 
                        " to a boolean: must be a String");
725
 
            }
726
 
         }
727
 
      }
728
 
   }
729
 
   
730
 
   private void start()
731
 
   {
732
 
      metadata.put(ServerInvoker.TIMEOUT, Integer.toString(pingTimeout));
733
 
      configMap = createPingConfig(client.getConfiguration(), metadata);
734
 
      log.debug(this + ": pingPeriod:  " + this.pingPeriod);
735
 
      log.debug(this + ": pingTimeout: " + this.pingTimeout);
736
 
      log.debug(this + ": ping retries: " + configMap.get("NumberOfCallRetries"));
737
 
 
738
 
      try
739
 
      {
740
 
         clientInvoker = InvokerRegistry.createClientInvoker(locator, configMap);
741
 
      }
742
 
      catch (Exception e)
743
 
      {
744
 
         log.debug("Unable to create client invoker for locator: " + locator);
745
 
         throw new RuntimeException("Unable to create client invoker for locator: " + locator, e);
746
 
      }
747
 
 
748
 
      if (!clientInvoker.isConnected())
749
 
      {
750
 
         if (trace) { log.trace("inner client invoker not connected, connecting ..."); }
751
 
         clientInvoker.connect();
752
 
      }
753
 
      
754
 
      started = true;
755
 
      timer = new Timer(true);
756
 
      
757
 
      try
758
 
      {
759
 
          TimerUtil.schedule(this, pingPeriod);
760
 
      }
761
 
      catch (Exception e)
762
 
      {
763
 
         log.error(this + " unable to schedule on TimerUtil", e);
764
 
         started = false;
765
 
         timer = null;
766
 
         return;
767
 
      }
768
 
      log.debug(this + " started");
769
 
   }
770
 
   
771
 
   private boolean doCheckConnectionWithLease() throws Throwable
772
 
   {
773
 
      boolean pingWorked = false;
774
 
 
775
 
      try
776
 
      {
777
 
         Map metadata = new HashMap();
778
 
         metadata.put(ServerInvoker.INVOKER_SESSION_ID, invokerSessionId);
779
 
         InvocationRequest ir =
780
 
            new InvocationRequest(null, Subsystem.SELF, "$PING$", metadata, null, null);
781
 
 
782
 
         if (trace) { log.trace("pinging, sending " + ir + " over " + clientInvoker); }
783
 
 
784
 
         Object o = clientInvoker.invoke(ir);
785
 
         if (o instanceof Boolean && !((Boolean) o).booleanValue())
786
 
         {
787
 
            // Server indicates lease has stopped.
788
 
            throw new Exception();
789
 
         }
790
 
 
791
 
         if (trace) { log.trace("ConnectionValidator got successful ping using " + clientInvoker);}
792
 
 
793
 
         pingWorked = true;
794
 
      }
795
 
      catch (Throwable t)
796
 
      {
797
 
         log.debug("ConnectionValidator failed to ping via " + clientInvoker, t);
798
 
      }
799
 
 
800
 
      return pingWorked;
801
 
   }
802
 
   
803
 
   private boolean doCheckConnectionWithoutLease() throws Throwable
804
 
   {
805
 
      boolean pingWorked = false;
806
 
 
807
 
      try
808
 
      {
809
 
         // Sending null client id as don't want to trigger lease on server side. This also means
810
 
         // that client connection validator will NOT impact client lease, so can not depend on it
811
 
         // to maintain client lease with the server.
812
 
         InvocationRequest ir =
813
 
            new InvocationRequest(null, Subsystem.SELF, "$PING$", null, null, null);
814
 
 
815
 
         if (trace) { log.trace("pinging, sending " + ir + " over " + clientInvoker); }
816
 
 
817
 
         clientInvoker.invoke(ir);
818
 
 
819
 
         if (trace) { log.trace("ConnectionValidator got successful ping using " + clientInvoker);}
820
 
 
821
 
         pingWorked = true;
822
 
      }
823
 
      catch (Throwable t)
824
 
      {
825
 
         log.debug("ConnectionValidator failed to ping via " + clientInvoker, t);
826
 
      }
827
 
 
828
 
      return pingWorked;
829
 
   }
830
 
 
831
 
   private boolean doStop()
832
 
   {
833
 
      if (trace) log.trace("entering doStop()");
834
 
      synchronized(lock)
835
 
      {
836
 
         if (stopped)
837
 
         {
838
 
            return false;
839
 
         }
840
 
         
841
 
         if (!listeners.isEmpty())
842
 
         {
843
 
            listeners.clear();
844
 
         }
845
 
         stopping = true;
846
 
         stopped = true;
847
 
         timer = null;
848
 
      }
849
 
 
850
 
      if (clientInvoker != null)
851
 
      {
852
 
         InvokerRegistry.destroyClientInvoker(locator, configMap);
853
 
      }
854
 
 
855
 
      TimerUtil.unschedule(this);
856
 
 
857
 
      boolean result = super.cancel();
858
 
      log.debug(this + " stopped, returning " + result);
859
 
      return result;
860
 
   }
861
 
   
862
 
   // Inner classes --------------------------------------------------------------------------------
863
 
 
864
 
   private class WaitOnConnectionCheckTimerTask extends TimerTask
865
 
   {
866
 
      public void run()
867
 
      {
868
 
         long start = System.currentTimeMillis();
869
 
         synchronized (notificationLock)
870
 
         {
871
 
            while (true)
872
 
            {
873
 
               int elapsed = (int) (System.currentTimeMillis() - start);
874
 
               int wait = pingTimeout - elapsed;
875
 
               if (wait <= 0)
876
 
               {
877
 
                  break;
878
 
               }
879
 
               
880
 
               try
881
 
               {
882
 
                  notificationLock.wait(wait);
883
 
                  break;
884
 
               }
885
 
               catch (InterruptedException e)
886
 
               {
887
 
                  continue;
888
 
               }
889
 
            }
890
 
         }
891
 
         
892
 
         if (!isValid)
893
 
         {
894
 
            log.debug(ConnectionValidator.this + "'s connection is invalid");
895
 
            ConnectionValidator.super.cancel();
896
 
            
897
 
            if (stopLeaseOnFailure)
898
 
            {
899
 
               if (trace) log.trace(ConnectionValidator.this + " detected connection failure: stopping LeasePinger");
900
 
               if (leasePinger != null)
901
 
               {
902
 
                  log.debug(ConnectionValidator.this + " shutting down lease pinger: " + leasePinger);
903
 
                  int disconnectTimeout = (failureDisconnectTimeout == -1) ? client.getDisconnectTimeout() : failureDisconnectTimeout;
904
 
                  if (trace) log.trace(ConnectionValidator.this + " disconnectTimeout: " + disconnectTimeout);
905
 
                  sharedInvoker.terminateLease(null, disconnectTimeout, leasePinger);
906
 
               }
907
 
               else
908
 
               {
909
 
                  if (trace) log.trace(ConnectionValidator.this + ": lease pinger == null: perhaps leasing is not enabled for this connection");
910
 
                  notifyListeners(new Exception("Could not connect to server!"));
911
 
               }
912
 
               
913
 
               cancel();
914
 
            }
915
 
            if (!useClientConnectionIdentity)
916
 
            {
917
 
                notifyListeners(new Exception("Could not connect to server!"));
918
 
            }
919
 
         }
920
 
      }
921
 
   }
922
 
   
923
 
   private static class ConnectionCheckThread extends Thread
924
 
   {
925
 
      private InvocationRequest ir;
926
 
      private ClientInvoker clientInvoker;
927
 
      private boolean isValid;
928
 
 
929
 
      public ConnectionCheckThread(ClientInvoker clientInvoker, InvocationRequest ir)
930
 
      {
931
 
         this.clientInvoker = clientInvoker;
932
 
         this.ir = ir;
933
 
         setDaemon(true);
934
 
      }
935
 
      
936
 
      public void run()
937
 
      {
938
 
         try
939
 
         {
940
 
            if (trace) { log.trace("pinging, sending " + ir + " over " + clientInvoker); }
941
 
            clientInvoker.invoke(ir);
942
 
            isValid = true;
943
 
            if (trace) { log.trace("ConnectionValidator got successful ping using " + clientInvoker);}
944
 
         }
945
 
         catch (Throwable t)
946
 
         {
947
 
            log.debug("ConnectionValidator failed to ping via " + clientInvoker, t);
948
 
         }
949
 
      }
950
 
      
951
 
      public boolean isValid()
952
 
      {
953
 
         return isValid;
954
 
      }
955
 
   }
956
 
}
 
 
b'\\ No newline at end of file'