com.zeroc.IceInternal.RouterInfo Maven / Gradle / Ivy
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package com.zeroc.IceInternal;
public final class RouterInfo
{
interface GetClientEndpointsCallback
{
void setEndpoints(EndpointI[] endpoints);
void setException(com.zeroc.Ice.LocalException ex);
}
interface AddProxyCallback
{
void addedProxy();
void setException(com.zeroc.Ice.LocalException ex);
}
RouterInfo(com.zeroc.Ice.RouterPrx router)
{
_router = router;
assert(_router != null);
}
synchronized public void
destroy()
{
_clientEndpoints = new EndpointI[0];
_adapter = null;
_identities.clear();
}
@Override
public boolean
equals(java.lang.Object obj)
{
if(this == obj)
{
return true;
}
if(obj instanceof RouterInfo)
{
return _router.equals(((RouterInfo)obj)._router);
}
return false;
}
@Override
public int
hashCode()
{
return _router.hashCode();
}
public com.zeroc.Ice.RouterPrx
getRouter()
{
//
// No mutex lock necessary, _router is immutable.
//
return _router;
}
public EndpointI[]
getClientEndpoints()
{
synchronized(this)
{
if(_clientEndpoints != null) // Lazy initialization.
{
return _clientEndpoints;
}
}
com.zeroc.Ice.Router.GetClientProxyResult r = _router.getClientProxy();
return setClientEndpoints(r.returnValue, r.hasRoutingTable.orElse(true));
}
public void
getClientEndpoints(final GetClientEndpointsCallback callback)
{
EndpointI[] clientEndpoints = null;
synchronized(this)
{
clientEndpoints = _clientEndpoints;
}
if(clientEndpoints != null)
{
callback.setEndpoints(clientEndpoints);
return;
}
_router.getClientProxyAsync().whenComplete((com.zeroc.Ice.Router.GetClientProxyResult r, Throwable ex) ->
{
if(ex != null)
{
if(ex instanceof com.zeroc.Ice.LocalException)
{
callback.setException((com.zeroc.Ice.LocalException)ex);
}
else
{
callback.setException(new com.zeroc.Ice.UnknownException(ex));
}
}
else
{
callback.setEndpoints(setClientEndpoints(r.returnValue, r.hasRoutingTable.orElse(true)));
}
});
}
public EndpointI[]
getServerEndpoints()
{
com.zeroc.Ice.ObjectPrx serverProxy = _router.getServerProxy();
if(serverProxy == null)
{
throw new com.zeroc.Ice.NoEndpointException();
}
serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
return ((com.zeroc.Ice._ObjectPrxI)serverProxy)._getReference().getEndpoints();
}
public boolean
addProxy(final com.zeroc.Ice.ObjectPrx proxy, final AddProxyCallback callback)
{
assert(proxy != null);
synchronized(this)
{
if(!_hasRoutingTable)
{
return true; // The router implementation doesn't maintain a routing table.
}
if(_identities.contains(proxy.ice_getIdentity()))
{
//
// Only add the proxy to the router if it's not already in our local map.
//
return true;
}
}
_router.addProxiesAsync(new com.zeroc.Ice.ObjectPrx[] { proxy }).whenComplete(
(com.zeroc.Ice.ObjectPrx[] evictedProxies, Throwable ex) ->
{
if(ex != null)
{
if(ex instanceof com.zeroc.Ice.LocalException)
{
callback.setException((com.zeroc.Ice.LocalException)ex);
}
else
{
callback.setException(new com.zeroc.Ice.UnknownException(ex));
}
}
else
{
addAndEvictProxies(proxy, evictedProxies);
callback.addedProxy();
}
});
return false;
}
public synchronized void
setAdapter(com.zeroc.Ice.ObjectAdapter adapter)
{
_adapter = adapter;
}
public synchronized com.zeroc.Ice.ObjectAdapter
getAdapter()
{
return _adapter;
}
public synchronized void clearCache(Reference ref)
{
_identities.remove(ref.getIdentity());
}
private synchronized EndpointI[]
setClientEndpoints(com.zeroc.Ice.ObjectPrx clientProxy, boolean hasRoutingTable)
{
if(_clientEndpoints == null)
{
_hasRoutingTable = hasRoutingTable;
if(clientProxy == null)
{
//
// If getClientProxy() return nil, use router endpoints.
//
_clientEndpoints = ((com.zeroc.Ice._ObjectPrxI)_router)._getReference().getEndpoints();
}
else
{
clientProxy = clientProxy.ice_router(null); // The client proxy cannot be routed.
//
// In order to avoid creating a new connection to the
// router, we must use the same timeout as the already
// existing connection.
//
if(_router.ice_getConnection() != null)
{
clientProxy = clientProxy.ice_timeout(_router.ice_getConnection().timeout());
}
_clientEndpoints = ((com.zeroc.Ice._ObjectPrxI)clientProxy)._getReference().getEndpoints();
}
}
return _clientEndpoints;
}
private synchronized void
addAndEvictProxies(com.zeroc.Ice.ObjectPrx proxy, com.zeroc.Ice.ObjectPrx[] evictedProxies)
{
//
// Check if the proxy hasn't already been evicted by a
// concurrent addProxies call. If it's the case, don't
// add it to our local map.
//
int index = _evictedIdentities.indexOf(proxy.ice_getIdentity());
if(index >= 0)
{
_evictedIdentities.remove(index);
}
else
{
//
// If we successfully added the proxy to the router,
// we add it to our local map.
//
_identities.add(proxy.ice_getIdentity());
}
//
// We also must remove whatever proxies the router evicted.
//
for(com.zeroc.Ice.ObjectPrx p : evictedProxies)
{
if(!_identities.remove(p.ice_getIdentity()))
{
//
// It's possible for the proxy to not have been
// added yet in the local map if two threads
// concurrently call addProxies.
//
_evictedIdentities.add(p.ice_getIdentity());
}
}
}
private final com.zeroc.Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
private com.zeroc.Ice.ObjectAdapter _adapter;
private java.util.Set _identities = new java.util.HashSet<>();
private java.util.List _evictedIdentities = new java.util.ArrayList<>();
private boolean _hasRoutingTable;
}