KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aspects > remoting > ClusterChooserInterceptor


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 package org.jboss.aspects.remoting;
23
24 import org.jboss.aop.DispatcherConnectException;
25 import org.jboss.aop.util.PayloadKey;
26 import org.jboss.ha.framework.interfaces.GenericClusteringException;
27 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
28 import org.jboss.remoting.CannotConnectException;
29 import org.jboss.remoting.InvokerLocator;
30
31 import java.util.ArrayList JavaDoc;
32
33 /**
34  * Pick an invocation target
35  *
36  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
37  * @version $Revision: 54917 $
38  */

39 public class ClusterChooserInterceptor implements org.jboss.aop.advice.Interceptor, ClusterConstants, java.io.Serializable JavaDoc
40 {
41    private static final long serialVersionUID = -8666382019058421135L;
42
43    public static final ClusterChooserInterceptor singleton = new ClusterChooserInterceptor();
44
45    public String JavaDoc getName()
46    {
47       return "ClusterChooserInterceptor";
48    }
49
50    public Object JavaDoc invoke(org.jboss.aop.joinpoint.Invocation invocation)
51    throws Throwable JavaDoc
52    {
53       LoadBalancePolicy lb = (LoadBalancePolicy) invocation.getMetaData(CLUSTERED_REMOTING, LOADBALANCE_POLICY);
54       FamilyWrapper family = (FamilyWrapper) invocation.getMetaData(CLUSTERED_REMOTING, CLUSTER_FAMILY_WRAPPER);
55
56       // we give the opportunity, to any server interceptor, to know if this a
57
// first invocation to a node or if it is a failovered call
58
//
59
int failoverCounter = 0;
60       String JavaDoc familyName = family.get().getFamilyName();
61       invocation.getMetaData().addMetaData(CLUSTERED_REMOTING, CLUSTER_FAMILY, familyName, PayloadKey.AS_IS);
62       InvokerLocator target = (InvokerLocator) lb.chooseTarget(family.get());
63       Throwable JavaDoc lastException = null;
64       while (target != null)
65       {
66          invocation.getMetaData().addMetaData(CLUSTERED_REMOTING, FAILOVER_COUNTER, new Integer JavaDoc(failoverCounter), PayloadKey.AS_IS);
67          invocation.getMetaData().addMetaData(InvokeRemoteInterceptor.REMOTING, InvokeRemoteInterceptor.INVOKER_LOCATOR, target, PayloadKey.AS_IS);
68          invocation.getMetaData().addMetaData(CLUSTERED_REMOTING, CLUSTER_VIEW_ID, new Long JavaDoc(family.get().getCurrentViewId()), PayloadKey.AS_IS);
69
70          boolean definitivlyRemoveNodeOnFailure = true;
71          lastException = null;
72          try
73          {
74
75
76
77             Object JavaDoc rsp = invocation.invokeNext();
78             ArrayList JavaDoc newReplicants = (ArrayList JavaDoc) invocation.getResponseAttachment("replicants");
79             if (newReplicants != null)
80             {
81                long newViewId = ((Long JavaDoc) invocation.getResponseAttachment("viewId")).longValue();
82                family.get().updateClusterInfo(newReplicants, newViewId);
83             }
84             return rsp;
85          }
86          catch(DispatcherConnectException dce)
87          {
88             //In case of graceful shutdown, the target object will no longer exist in the Dispatcher,
89
//fail over to another server if we can...
90
//For now remove the node "definitely"
91
lastException = dce;
92          }
93          catch (CannotConnectException ex)
94          {
95             lastException = ex;
96          }
97          catch (GenericClusteringException gce)
98          {
99             lastException = gce;
100             // this is a generic clustering exception that contain the
101
// completion status: usefull to determine if we are authorized
102
// to re-issue a query to another node
103
//
104
if (gce.getCompletionStatus() == GenericClusteringException.COMPLETED_NO)
105             {
106                // we don't want to remove the node from the list of failed
107
// node UNLESS there is a risk to indefinitively loop
108
//
109
if (family.get().getTargets().size() >= failoverCounter)
110                {
111                   if (!gce.isDefinitive())
112                      definitivlyRemoveNodeOnFailure = false;
113                }
114             }
115             else
116             {
117                throw new RuntimeException JavaDoc("Clustering exception thrown", gce);
118             }
119          }
120          catch (Throwable JavaDoc t)
121          {
122             // Just in case this get wrapped in a Throwable. This can happen when
123
// the exception is generated inside the container and it is wrapped in
124
// a ForwardId exception.
125
if(t.getCause() instanceof GenericClusteringException)
126             {
127                GenericClusteringException gce = (GenericClusteringException)t.getCause();
128                lastException = gce;
129                // this is a generic clustering exception that contain the
130
// completion status: usefull to determine if we are authorized
131
// to re-issue a query to another node
132
//
133
if (gce.getCompletionStatus() == GenericClusteringException.COMPLETED_NO)
134                {
135                   // we don't want to remove the node from the list of failed
136
// node UNLESS there is a risk to indefinitively loop
137
//
138
if (family.get().getTargets().size() >= failoverCounter)
139                   {
140                      if (!gce.isDefinitive())
141                         definitivlyRemoveNodeOnFailure = false;
142                   }
143                }
144                else
145                {
146                   throw new RuntimeException JavaDoc("Clustering exception thrown", gce);
147                }
148             } else
149             {
150                throw t;
151             }
152          }
153
154          // If we reach here, this means that we must fail-over
155
family.get().removeDeadTarget(target);
156          if (!definitivlyRemoveNodeOnFailure)
157          {
158             family.get().resetView();
159          }
160
161          target = (InvokerLocator) lb.chooseTarget(family.get());
162          if (target == null)
163          {
164             if (lastException != null)
165             {
166                throw new RuntimeException JavaDoc("cluster invocation failed, last exception was: ", lastException);
167             }
168             else
169             {
170                throw new RuntimeException JavaDoc("cluster invocation failed");
171             }
172          }
173          failoverCounter++;
174       }
175       // if we get here this means list was exhausted
176
throw new RuntimeException JavaDoc("Unreachable?: Service unavailable.");
177    }
178 }
179
Popular Tags