1 22 package org.jboss.invocation.http.interfaces; 23 24 import java.io.Externalizable ; 25 import java.io.IOException ; 26 import java.io.ObjectInput ; 27 import java.io.ObjectOutput ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.net.URL ; 30 import java.rmi.ServerException ; 31 import java.util.ArrayList ; 32 import java.util.List ; 33 34 import org.jboss.ha.framework.interfaces.ClusteringTargetsRepository; 35 import org.jboss.ha.framework.interfaces.GenericClusteringException; 36 import org.jboss.ha.framework.interfaces.HARMIResponse; 37 import org.jboss.ha.framework.interfaces.LoadBalancePolicy; 38 import org.jboss.ha.framework.interfaces.FamilyClusterInfo; 39 import org.jboss.invocation.Invocation; 40 import org.jboss.invocation.InvocationException; 41 import org.jboss.invocation.Invoker; 42 import org.jboss.invocation.InvokerProxyHA; 43 import org.jboss.invocation.MarshalledInvocation; 44 import org.jboss.invocation.PayloadKey; 45 import org.jboss.logging.Logger; 46 47 56 public class HttpInvokerProxyHA 57 implements InvokerProxyHA, Invoker, Externalizable 58 { 59 private static Logger log = Logger.getLogger(HttpInvokerProxyHA.class); 61 62 65 private static final long serialVersionUID = -7081220026780794383L; 66 67 69 protected LoadBalancePolicy loadBalancePolicy; 71 protected String proxyFamilyName = null; 72 protected FamilyClusterInfo familyClusterInfo = null; 73 74 protected transient boolean trace = false; 75 76 public HttpInvokerProxyHA() 78 { 79 } 81 82 89 public HttpInvokerProxyHA(List targets, long viewId, LoadBalancePolicy policy, 90 String proxyFamilyName) 91 { 92 this.familyClusterInfo = ClusteringTargetsRepository.initTarget (proxyFamilyName, targets, viewId); 93 this.loadBalancePolicy = policy; 94 this.proxyFamilyName = proxyFamilyName; 95 this.trace = log.isTraceEnabled(); 96 if( trace ) 97 log.trace("Init, cluterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy); 98 } 99 100 102 public void updateClusterInfo (ArrayList targets, long viewId) 103 { 104 if (familyClusterInfo != null) 105 this.familyClusterInfo.updateClusterInfo (targets, viewId); 106 } 107 108 public String getServerHostName() throws Exception 109 { 110 return null; 111 } 112 113 public FamilyClusterInfo getClusterInfo() 114 { 115 return familyClusterInfo; 116 } 117 118 public Object getRemoteTarget() 119 { 120 return getRemoteTarget(null); 121 } 122 public Object getRemoteTarget(Invocation invocationBasedRouting) 123 { 124 Object target = loadBalancePolicy.chooseTarget(this.familyClusterInfo, invocationBasedRouting); 125 if( trace ) 126 log.trace("Choose remoteTarget: "+target); 127 return target; 128 } 129 130 public void remoteTargetHasFailed(Object target) 131 { 132 removeDeadTarget(target); 133 } 134 135 protected int totalNumberOfTargets () 136 { 137 int size = 0; 138 if( familyClusterInfo != null ) 139 size = familyClusterInfo.getTargets().size(); 140 return size; 141 } 142 143 protected void removeDeadTarget(Object target) 144 { 145 if( familyClusterInfo != null ) 146 { 147 List targets = familyClusterInfo.removeDeadTarget(target); 148 if( trace ) 149 { 150 log.trace("removeDeadTarget("+target+"), targets.size="+targets.size()); 151 } 152 } 153 } 154 protected void resetView () 155 { 156 familyClusterInfo.resetView(); 157 } 158 159 162 public Object invoke(Invocation invocation) 163 throws Exception 164 { 165 int failoverCounter = 0; 169 170 MarshalledInvocation mi = new MarshalledInvocation(invocation); 172 mi.setValue("CLUSTER_VIEW_ID", new Long (familyClusterInfo.getCurrentViewId())); 173 String target = (String ) getRemoteTarget(invocation); 174 URL externalURL = Util.resolveURL(target); 175 Exception lastException = null; 176 while( externalURL != null ) 177 { 178 boolean definitivlyRemoveNodeOnFailure = true; 179 invocation.setValue("FAILOVER_COUNTER", new Integer (failoverCounter), PayloadKey.AS_IS); 180 try 181 { 182 if( trace ) 183 log.trace("Invoking on target="+externalURL); 184 Object rtn = Util.invoke(externalURL, mi); 185 HARMIResponse rsp = (HARMIResponse) rtn; 186 187 if (rsp.newReplicants != null) 188 updateClusterInfo(rsp.newReplicants, rsp.currentViewId); 189 return rsp.response; 190 } 191 catch(GenericClusteringException e) 192 { 193 if( e.getCompletionStatus() != e.COMPLETED_NO ) 198 { 199 if (totalNumberOfTargets() >= failoverCounter) 202 { 203 if( e.isDefinitive() == false ) 204 definitivlyRemoveNodeOnFailure = false; 205 } 206 } 207 else 208 { 209 throw new ServerException ("Cannot proceed beyond target="+externalURL, e); 210 } 211 } 212 catch(InvocationException e) 213 { 214 Throwable cause = e.getTargetException(); 216 if( cause instanceof Exception ) 217 throw (Exception ) cause; 218 else if (cause instanceof Error ) 219 throw (Error ) cause; 220 throw new InvocationTargetException (cause); 221 } 222 catch(IOException e) 223 { 224 if( trace ) 225 log.trace("Invoke failed, target="+externalURL, e); 226 lastException = e; 227 } 228 catch(Exception e) 229 { 230 throw e; 232 } 233 234 remoteTargetHasFailed(target); 236 if( definitivlyRemoveNodeOnFailure ) 237 resetView(); 238 target = (String ) getRemoteTarget(invocation); 239 externalURL = Util.resolveURL(target); 240 failoverCounter ++; 241 } 242 throw new ServerException ("Service unavailable last exception:", lastException); 244 } 245 246 248 public void writeExternal(final ObjectOutput out) 249 throws IOException 250 { 251 List currentTargets = null; 253 long vid = 0; 254 synchronized (this.familyClusterInfo) 255 { 256 currentTargets = this.familyClusterInfo.getTargets (); 257 vid = this.familyClusterInfo.getCurrentViewId (); 258 } 259 out.writeObject(currentTargets); 260 out.writeLong(vid); 261 out.writeObject(this.loadBalancePolicy); 262 out.writeObject(this.proxyFamilyName); 263 } 264 265 267 public void readExternal(final ObjectInput in) 268 throws IOException , ClassNotFoundException 269 { 270 List targets = (List ) in.readObject(); 271 long vid = in.readLong (); 272 this.loadBalancePolicy = (LoadBalancePolicy) in.readObject(); 273 this.proxyFamilyName = (String )in.readObject(); 274 this.trace = log.isTraceEnabled(); 275 276 this.familyClusterInfo = ClusteringTargetsRepository.initTarget(this.proxyFamilyName, targets, vid); 278 if( trace ) 279 log.trace("Init, clusterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy); 280 } 281 } 282 283 | Popular Tags |