1 22 package org.jboss.ha.framework.interfaces; 23 24 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.io.ObjectOutputStream ; 28 import java.lang.reflect.Method ; 29 import java.util.ArrayList ; 30 import java.util.List ; 31 32 import org.jboss.invocation.MarshalledInvocation; 33 import org.jboss.logging.Logger; 34 35 42 public class HARMIClient 43 implements HARMIProxy, java.lang.reflect.InvocationHandler , java.io.Serializable 44 { 45 49 private static final long serialVersionUID = -1227816478666532463L; 50 private static final Logger log = Logger.getLogger(HARMIClient.class); 51 52 53 protected static final Method TO_STRING; 54 55 56 protected static final Method HASH_CODE; 57 58 59 protected static final Method EQUALS; 60 61 static 62 { 63 try 64 { 65 final Class [] empty = {}; 66 final Class type = Object .class; 67 68 TO_STRING = type.getMethod("toString", empty); 69 HASH_CODE = type.getMethod("hashCode", empty); 70 EQUALS = type.getMethod("equals", new Class [] { type }); 71 } 72 catch (Exception e) 73 { 74 e.printStackTrace(); 75 throw new ExceptionInInitializerError (e); 76 } 77 } 78 79 81 protected String key = null; 82 protected LoadBalancePolicy loadBalancePolicy; 84 protected transient Object local = null; 86 protected transient boolean trace; 87 FamilyClusterInfo familyClusterInfo = null; 88 89 91 93 public HARMIClient() {} 94 95 public HARMIClient(List targets, LoadBalancePolicy policy, String key) 96 { 97 this(targets, 0, policy, key, null); 98 } 99 100 public HARMIClient(List targets, 101 long initViewId, 102 LoadBalancePolicy policy, 103 String key, 104 Object local) 105 { 106 this.familyClusterInfo = ClusteringTargetsRepository.initTarget (key, targets, initViewId); 107 108 this.loadBalancePolicy = policy; 110 this.loadBalancePolicy.init(this); 111 this.key = key; 112 this.local = local; 113 this.trace = log.isTraceEnabled(); 114 if( trace ) 115 log.trace("Init, cluterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy); 116 } 117 118 134 public void updateClusterInfo (ArrayList targets, long viewId) 135 { 136 if (familyClusterInfo != null) 137 this.familyClusterInfo.updateClusterInfo (targets, viewId); 138 } 139 140 public Object getRemoteTarget() 141 { 142 return loadBalancePolicy.chooseTarget(this.familyClusterInfo, null); } 145 146 public void remoteTargetHasFailed(Object target) 147 { 148 removeDeadTarget(target); 149 } 150 151 152 public Method findLocalMethod(Method method, Object [] args) throws Exception 153 { 154 return method; 155 } 156 157 158 public Object invokeRemote(Object proxy, Method method, Object [] args) throws Throwable 159 { 160 boolean trace = log.isTraceEnabled(); 161 HARMIServer target = (HARMIServer)getRemoteTarget(); 162 while (target != null) 163 { 164 Exception lastException = null; 165 try 166 { 167 if( trace ) 168 log.trace("Invoking on target="+target); 169 MarshalledInvocation mi = new MarshalledInvocation(null, method, args, null, null, null); 170 mi.setObjectName (""); HARMIResponse rsp = target.invoke(this.familyClusterInfo.getCurrentViewId (), mi); 174 if (rsp.newReplicants != null) 175 { 176 if( trace ) 177 { 178 log.trace("newReplicants: "+rsp.newReplicants); 179 } 180 updateClusterInfo (rsp.newReplicants, rsp.currentViewId); 181 } 184 185 return rsp.response; 186 } 187 catch (java.rmi.ConnectException e) 188 { 189 lastException = e; 190 } 191 catch (java.rmi.ConnectIOException e) 192 { 193 lastException = e; 194 } 195 catch (java.rmi.NoSuchObjectException e) 196 { 197 lastException = e; 198 } 199 catch (java.rmi.UnmarshalException e) 200 { 201 lastException = e; 202 } 203 catch (java.rmi.UnknownHostException e) 204 { 205 lastException = e; 206 } 207 if( trace ) 208 log.trace("Invoke failed, target="+target, lastException); 209 remoteTargetHasFailed(target); 211 target = (HARMIServer)getRemoteTarget(); 212 } 213 throw new java.rmi.RemoteException ("Service unavailable."); 215 216 } 217 218 220 public boolean isLocal() 221 { 222 return local != null; 223 } 224 225 227 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable 228 { 229 String name = method.getName(); 231 if (method.equals(TO_STRING)) 232 { 233 StringBuffer tmp = new StringBuffer (super.toString()); 234 tmp.append('('); 235 tmp.append(familyClusterInfo); 236 tmp.append(')'); 237 return tmp.toString(); 238 } 239 else if (name.equals("equals")) 240 { 241 return method.invoke(this, args); 242 } 243 else if (name.equals("hashCode")) 244 { 245 return method.invoke(this, args); 246 } 247 else if (name.equals("isLocal") && (args == null || args.length == 0)) 248 { 249 return method.invoke(this, args); 250 } 251 252 if (local != null) 255 { 256 try 257 { 258 Method localMethod = findLocalMethod(method, args); 259 return localMethod.invoke(local, args); 260 } 261 catch (java.lang.reflect.InvocationTargetException ite) 262 { 263 throw ite.getTargetException(); 264 } 265 } 266 else 267 { 268 return invokeRemote(null, method, args); 269 } 270 } 271 272 274 276 protected void removeDeadTarget(Object target) 277 { 278 if (this.familyClusterInfo != null) 280 this.familyClusterInfo.removeDeadTarget (target); 281 } 282 283 285 private void readObject (ObjectInputStream stream) 286 throws IOException , ClassNotFoundException 287 { 288 this.key = stream.readUTF(); 289 List targets = (List )stream.readObject(); 290 long vid = stream.readLong (); 291 this.loadBalancePolicy = (LoadBalancePolicy)stream.readObject(); 292 HARMIServer server = (HARMIServer)HARMIServer.rmiServers.get(key); 293 294 this.familyClusterInfo = ClusteringTargetsRepository.initTarget (this.key, targets, vid); 297 298 this.loadBalancePolicy.init(this); 299 300 if (server != null) 301 { 302 synchronized (targets) 303 { 304 try 305 { 306 targets = (List )server.getReplicants(); 307 local = server.getLocal(); 308 } 309 catch (Exception ignored) 310 {} 311 } 312 } 313 this.trace = log.isTraceEnabled(); 314 if( trace ) 315 log.trace("Init, clusterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy); 316 } 317 private void writeObject (ObjectOutputStream stream) 318 throws IOException 319 { 320 List currentTargets = null; 322 long vid = 0; 323 synchronized (this.familyClusterInfo) 324 { 325 currentTargets = this.familyClusterInfo.getTargets (); 326 vid = this.familyClusterInfo.getCurrentViewId (); 327 } 328 stream.writeUTF(key); 329 stream.writeObject(currentTargets); 330 stream.writeLong(vid); 331 stream.writeObject(loadBalancePolicy); 332 333 } 334 335 } | Popular Tags |