package org.jboss.ha.framework.interfaces;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.jboss.invocation.MarshalledInvocation;
public class HARMIClient
implements HARMIProxy, java.lang.reflect.InvocationHandler, java.io.Serializable
{
private static final long serialVersionUID = -1227816478666532463L;
protected String key = null;
protected LoadBalancePolicy loadBalancePolicy;
protected transient Object local = null;
FamilyClusterInfo familyClusterInfo = null;
public HARMIClient() {}
public HARMIClient(ArrayList targets, LoadBalancePolicy policy, String key)
{
this.familyClusterInfo = ClusteringTargetsRepository.initTarget (key, targets, 0L);
this.loadBalancePolicy = policy;
this.loadBalancePolicy.init(this);
this.key = key;
}
public HARMIClient(ArrayList targets,
long initViewId,
LoadBalancePolicy policy,
String key,
Object local)
{
this.familyClusterInfo = ClusteringTargetsRepository.initTarget (key, targets, initViewId);
this.loadBalancePolicy = policy;
this.loadBalancePolicy.init(this);
this.key = key;
this.local = local;
}
public void updateClusterInfo (ArrayList targets, long viewId)
{
if (familyClusterInfo != null)
this.familyClusterInfo.updateClusterInfo (targets, viewId);
}
public Object getRemoteTarget()
{
return loadBalancePolicy.chooseTarget(this.familyClusterInfo, null); }
public void remoteTargetHasFailed(Object target)
{
removeDeadTarget(target);
}
public Method findLocalMethod(Method method, Object[] args) throws Exception
{
return method;
}
public Object invokeRemote(Object proxy, Method method, Object[] args) throws Throwable
{
HARMIServer target = (HARMIServer)getRemoteTarget();
while (target != null)
{
try
{
MarshalledInvocation mi = new MarshalledInvocation(null, method, args, null, null, null);
mi.setObjectName (""); HARMIResponse rsp = target.invoke(this.familyClusterInfo.getCurrentViewId (), mi);
if (rsp.newReplicants != null)
{
updateClusterInfo (rsp.newReplicants, rsp.currentViewId);
}
return rsp.response;
}
catch (java.rmi.ConnectException ce)
{
}
catch (java.rmi.ConnectIOException cioe)
{
}
catch (java.rmi.NoSuchObjectException nsoe)
{
}
catch (java.rmi.UnmarshalException ue )
{
}
catch (java.rmi.UnknownHostException uhe)
{
}
remoteTargetHasFailed(target);
target = (HARMIServer)getRemoteTarget();
}
throw new java.rmi.RemoteException("Service unavailable.");
}
public boolean isLocal()
{
return local != null;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
if (method.getName().equals("isLocal") && (args == null || args.length == 0))
{
return method.invoke(this, args);
}
if (local != null)
{
try
{
Method localMethod = findLocalMethod(method, args);
return localMethod.invoke(local, args);
}
catch (java.lang.reflect.InvocationTargetException ite)
{
throw ite.getTargetException();
}
}
else
{
return invokeRemote(null, method, args);
}
}
protected void removeDeadTarget(Object target)
{
if (this.familyClusterInfo != null)
this.familyClusterInfo.removeDeadTarget (target);
}
private void readObject (ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
this.key = stream.readUTF();
ArrayList targets = (ArrayList)stream.readObject();
long vid = stream.readLong ();
this.loadBalancePolicy = (LoadBalancePolicy)stream.readObject();
HARMIServer server = (HARMIServer)HARMIServer.rmiServers.get(key);
this.familyClusterInfo = ClusteringTargetsRepository.initTarget (this.key, targets, vid);
this.loadBalancePolicy.init(this);
if (server != null)
{
synchronized (targets)
{
try
{
targets = (ArrayList)server.getReplicants();
local = server.getLocal();
}
catch (Exception ignored)
{}
}
}
}
private void writeObject (ObjectOutputStream stream)
throws IOException
{
ArrayList currentTargets = this.familyClusterInfo.getTargets ();
currentTargets.trimToSize ();
long vid = this.familyClusterInfo.getCurrentViewId ();
stream.writeUTF(key);
stream.writeObject(currentTargets);
stream.writeLong(vid);
stream.writeObject(loadBalancePolicy);
}
}