IceInternal.RoutableReference Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice-compat Show documentation
Show all versions of ice-compat Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
The newest version!
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package IceInternal;
public class RoutableReference extends Reference
{
@Override
public final EndpointI[]
getEndpoints()
{
return _endpoints;
}
@Override
public final String
getAdapterId()
{
return _adapterId;
}
@Override
public final LocatorInfo
getLocatorInfo()
{
return _locatorInfo;
}
@Override
public final RouterInfo
getRouterInfo()
{
return _routerInfo;
}
@Override
public final boolean
getCollocationOptimized()
{
return _collocationOptimized;
}
@Override
public final boolean
getCacheConnection()
{
return _cacheConnection;
}
@Override
public final boolean
getPreferSecure()
{
return _preferSecure;
}
@Override
public final Ice.EndpointSelectionType
getEndpointSelection()
{
return _endpointSelection;
}
@Override
public final int
getLocatorCacheTimeout()
{
return _locatorCacheTimeout;
}
@Override
public final String
getConnectionId()
{
return _connectionId;
}
@Override
public Ice.IntOptional
getTimeout()
{
return _overrideTimeout ? Ice.Optional.O(_timeout) : new Ice.IntOptional();
}
@Override
public Reference
changeEncoding(Ice.EncodingVersion newEncoding)
{
RoutableReference r = (RoutableReference)super.changeEncoding(newEncoding);
if(r != this)
{
LocatorInfo locInfo = r._locatorInfo;
if(locInfo != null && !locInfo.getLocator().ice_getEncodingVersion().equals(newEncoding))
{
r._locatorInfo = getInstance().locatorManager().get(
(Ice.LocatorPrx)locInfo.getLocator().ice_encodingVersion(newEncoding));
}
}
return r;
}
@Override
public Reference
changeCompress(boolean newCompress)
{
RoutableReference r = (RoutableReference)super.changeCompress(newCompress);
if(r != this && _endpoints.length > 0) // Also override the compress flag on the endpoints if it was updated.
{
EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
for(int i = 0; i < _endpoints.length; i++)
{
newEndpoints[i] = _endpoints[i].compress(newCompress);
}
r._endpoints = newEndpoints;
}
return r;
}
@Override
public Reference
changeEndpoints(EndpointI[] newEndpoints)
{
if(java.util.Arrays.equals(newEndpoints, _endpoints))
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._endpoints = newEndpoints;
r._adapterId = "";
r.applyOverrides(r._endpoints);
return r;
}
@Override
public Reference
changeAdapterId(String newAdapterId)
{
if(_adapterId.equals(newAdapterId))
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._adapterId = newAdapterId;
r._endpoints = _emptyEndpoints;
return r;
}
@Override
public Reference
changeLocator(Ice.LocatorPrx newLocator)
{
LocatorInfo newLocatorInfo = getInstance().locatorManager().get(newLocator);
if(newLocatorInfo != null && _locatorInfo != null && newLocatorInfo.equals(_locatorInfo))
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._locatorInfo = newLocatorInfo;
return r;
}
@Override
public Reference
changeRouter(Ice.RouterPrx newRouter)
{
RouterInfo newRouterInfo = getInstance().routerManager().get(newRouter);
if(newRouterInfo != null && _routerInfo != null && newRouterInfo.equals(_routerInfo))
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._routerInfo = newRouterInfo;
return r;
}
@Override
public Reference
changeCollocationOptimized(boolean newCollocationOptimized)
{
if(newCollocationOptimized == _collocationOptimized)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._collocationOptimized = newCollocationOptimized;
return r;
}
@Override
public final Reference
changeCacheConnection(boolean newCache)
{
if(newCache == _cacheConnection)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._cacheConnection = newCache;
return r;
}
@Override
public Reference
changePreferSecure(boolean newPreferSecure)
{
if(newPreferSecure == _preferSecure)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._preferSecure = newPreferSecure;
return r;
}
@Override
public final Reference
changeEndpointSelection(Ice.EndpointSelectionType newType)
{
if(newType == _endpointSelection)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._endpointSelection = newType;
return r;
}
@Override
public Reference
changeLocatorCacheTimeout(int newTimeout)
{
if(_locatorCacheTimeout == newTimeout)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._locatorCacheTimeout = newTimeout;
return r;
}
@Override
public Reference
changeTimeout(int newTimeout)
{
if(_overrideTimeout && _timeout == newTimeout)
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._timeout = newTimeout;
r._overrideTimeout = true;
if(_endpoints.length > 0)
{
EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
for(int i = 0; i < _endpoints.length; i++)
{
newEndpoints[i] = _endpoints[i].timeout(newTimeout);
}
r._endpoints = newEndpoints;
}
return r;
}
@Override
public Reference
changeConnectionId(String id)
{
if(_connectionId.equals(id))
{
return this;
}
RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
r._connectionId = id;
if(_endpoints.length > 0)
{
EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
for(int i = 0; i < _endpoints.length; i++)
{
newEndpoints[i] = _endpoints[i].connectionId(id);
}
r._endpoints = newEndpoints;
}
return r;
}
@Override
public Reference
changeConnection(Ice.ConnectionI connection)
{
return new FixedReference(getInstance(),
getCommunicator(),
getIdentity(),
getFacet(),
getMode(),
getSecure(),
getProtocol(),
getEncoding(),
connection,
getInvocationTimeout(),
getContext(),
getCompress());
}
@Override
public boolean
isIndirect()
{
return _endpoints.length == 0;
}
@Override
public boolean
isWellKnown()
{
return _endpoints.length == 0 && _adapterId.length() == 0;
}
@Override
public void
streamWrite(Ice.OutputStream s)
throws Ice.MarshalException
{
super.streamWrite(s);
s.writeSize(_endpoints.length);
if(_endpoints.length > 0)
{
assert(_adapterId.length() == 0);
for(EndpointI endpoint : _endpoints)
{
s.writeShort(endpoint.type());
endpoint.streamWrite(s);
}
}
else
{
s.writeString(_adapterId); // Adapter id.
}
}
@Override
public String
toString()
{
//
// WARNING: Certain features, such as proxy validation in Glacier2,
// depend on the format of proxy strings. Changes to toString() and
// methods called to generate parts of the reference string could break
// these features. Please review for all features that depend on the
// format of proxyToString() before changing this and related code.
//
StringBuilder s = new StringBuilder(128);
s.append(super.toString());
if(_endpoints.length > 0)
{
for(EndpointI endpoint : _endpoints)
{
String endp = endpoint.toString();
if(endp != null && endp.length() > 0)
{
s.append(':');
s.append(endp);
}
}
}
else if(_adapterId.length() > 0)
{
s.append(" @ ");
//
// If the encoded adapter id string contains characters which
// the reference parser uses as separators, then we enclose
// the adapter id string in quotes.
//
String a = IceUtilInternal.StringUtil.escapeString(_adapterId, null, getInstance().toStringMode());
if(IceUtilInternal.StringUtil.findFirstOf(a, " :@") != -1)
{
s.append('"');
s.append(a);
s.append('"');
}
else
{
s.append(a);
}
}
return s.toString();
}
@Override
public java.util.Map toProperty(String prefix)
{
java.util.Map properties = new java.util.HashMap();
properties.put(prefix, toString());
properties.put(prefix + ".CollocationOptimized", _collocationOptimized ? "1" : "0");
properties.put(prefix + ".ConnectionCached", _cacheConnection ? "1" : "0");
properties.put(prefix + ".PreferSecure", _preferSecure ? "1" : "0");
properties.put(prefix + ".EndpointSelection",
_endpointSelection == Ice.EndpointSelectionType.Random ? "Random" : "Ordered");
{
StringBuffer s = new StringBuffer();
s.append(getInvocationTimeout());
properties.put(prefix + ".InvocationTimeout", s.toString());
}
{
StringBuffer s = new StringBuffer();
s.append(_locatorCacheTimeout);
properties.put(prefix + ".LocatorCacheTimeout", s.toString());
}
if(_routerInfo != null)
{
Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_routerInfo.getRouter();
java.util.Map routerProperties = h._getReference().toProperty(prefix + ".Router");
for(java.util.Map.Entry p : routerProperties.entrySet())
{
properties.put(p.getKey(), p.getValue());
}
}
if(_locatorInfo != null)
{
Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_locatorInfo.getLocator();
java.util.Map locatorProperties = h._getReference().toProperty(prefix + ".Locator");
for(java.util.Map.Entry p : locatorProperties.entrySet())
{
properties.put(p.getKey(), p.getValue());
}
}
return properties;
}
@Override
public synchronized int
hashCode()
{
if(!_hashInitialized)
{
super.hashCode(); // Initializes _hashValue.
_hashValue = IceInternal.HashUtil.hashAdd(_hashValue, _adapterId);
}
return _hashValue;
}
@Override
public boolean
equals(java.lang.Object obj)
{
if(this == obj)
{
return true;
}
if(!(obj instanceof RoutableReference))
{
return false;
}
if(!super.equals(obj))
{
return false;
}
RoutableReference rhs = (RoutableReference)obj; // Guaranteed to succeed.
if(_locatorInfo == null ? rhs._locatorInfo != null : !_locatorInfo.equals(rhs._locatorInfo))
{
return false;
}
if(_routerInfo == null ? rhs._routerInfo != null : !_routerInfo.equals(rhs._routerInfo))
{
return false;
}
if(_collocationOptimized != rhs._collocationOptimized)
{
return false;
}
if(_cacheConnection != rhs._cacheConnection)
{
return false;
}
if(_preferSecure != rhs._preferSecure)
{
return false;
}
if(_endpointSelection != rhs._endpointSelection)
{
return false;
}
if(_locatorCacheTimeout != rhs._locatorCacheTimeout)
{
return false;
}
if(!_connectionId.equals(rhs._connectionId))
{
return false;
}
if(_overrideTimeout != rhs._overrideTimeout)
{
return false;
}
if(_overrideTimeout && _timeout != rhs._timeout)
{
return false;
}
if(!java.util.Arrays.equals(_endpoints, rhs._endpoints))
{
return false;
}
if(!_adapterId.equals(rhs._adapterId))
{
return false;
}
return true;
}
@Override
public RequestHandler
getRequestHandler(Ice.ObjectPrxHelperBase proxy)
{
return getInstance().requestHandlerFactory().getRequestHandler(this, proxy);
}
@Override
public BatchRequestQueue
getBatchRequestQueue()
{
return new BatchRequestQueue(getInstance(), getMode() == Reference.ModeBatchDatagram);
}
public void
getConnection(final GetConnectionCallback callback)
{
if(_routerInfo != null)
{
//
// If we route, we send everything to the router's client
// proxy endpoints.
//
_routerInfo.getClientEndpoints(new RouterInfo.GetClientEndpointsCallback()
{
@Override
public void
setEndpoints(EndpointI[] endpts)
{
if(endpts.length > 0)
{
applyOverrides(endpts);
createConnection(endpts, callback);
}
else
{
getConnectionNoRouterInfo(callback);
}
}
@Override
public void
setException(Ice.LocalException ex)
{
callback.setException(ex);
}
});
}
else
{
getConnectionNoRouterInfo(callback);
}
}
public void
getConnectionNoRouterInfo(final GetConnectionCallback callback)
{
if(_endpoints.length > 0)
{
createConnection(_endpoints, callback);
return;
}
final RoutableReference self = this;
if(_locatorInfo != null)
{
_locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorInfo.GetEndpointsCallback()
{
@Override
public void
setEndpoints(EndpointI[] endpoints, final boolean cached)
{
if(endpoints.length == 0)
{
callback.setException(new Ice.NoEndpointException(self.toString()));
return;
}
applyOverrides(endpoints);
createConnection(endpoints, new GetConnectionCallback()
{
@Override
public void
setConnection(Ice.ConnectionI connection, boolean compress)
{
callback.setConnection(connection, compress);
}
@Override
public void
setException(Ice.LocalException exc)
{
try
{
throw exc;
}
catch(Ice.NoEndpointException ex)
{
callback.setException(ex); // No need to retry if there's no endpoints.
}
catch(Ice.LocalException ex)
{
assert(_locatorInfo != null);
_locatorInfo.clearCache(self);
if(cached)
{
TraceLevels traceLvls = getInstance().traceLevels();
if(traceLvls.retry >= 2)
{
String s = "connection to cached endpoints failed\n" +
"removing endpoints from cache and trying again\n" + ex;
getInstance().initializationData().logger.trace(traceLvls.retryCat, s);
}
getConnectionNoRouterInfo(callback); // Retry.
return;
}
callback.setException(ex);
}
}
});
}
@Override
public void
setException(Ice.LocalException ex)
{
callback.setException(ex);
}
});
}
else
{
callback.setException(new Ice.NoEndpointException(toString()));
}
}
protected
RoutableReference(Instance instance,
Ice.Communicator communicator,
Ice.Identity identity,
String facet,
int mode,
boolean secure,
Ice.ProtocolVersion protocol,
Ice.EncodingVersion encoding,
EndpointI[] endpoints,
String adapterId,
LocatorInfo locatorInfo,
RouterInfo routerInfo,
boolean collocationOptimized,
boolean cacheConnection,
boolean prefereSecure,
Ice.EndpointSelectionType endpointSelection,
int locatorCacheTimeout,
int invocationTimeout,
java.util.Map context)
{
super(instance, communicator, identity, facet, mode, secure, protocol, encoding, invocationTimeout, context);
_endpoints = endpoints;
_adapterId = adapterId;
_locatorInfo = locatorInfo;
_routerInfo = routerInfo;
_collocationOptimized = collocationOptimized;
_cacheConnection = cacheConnection;
_preferSecure = prefereSecure;
_endpointSelection = endpointSelection;
_locatorCacheTimeout = locatorCacheTimeout;
_overrideTimeout = false;
_timeout = -1;
if(_endpoints == null)
{
_endpoints = _emptyEndpoints;
}
if(_adapterId == null)
{
_adapterId = "";
}
assert(_adapterId.length() == 0 || _endpoints.length == 0);
}
protected void
applyOverrides(EndpointI[] endpts)
{
//
// Apply the endpoint overrides to each endpoint.
//
for(int i = 0; i < endpts.length; ++i)
{
endpts[i] = endpts[i].connectionId(_connectionId);
if(_overrideCompress)
{
endpts[i] = endpts[i].compress(_compress);
}
if(_overrideTimeout)
{
endpts[i] = endpts[i].timeout(_timeout);
}
}
}
private EndpointI[]
filterEndpoints(EndpointI[] allEndpoints)
{
java.util.List endpoints = new java.util.ArrayList();
//
// Filter out opaque endpoints.
//
for(EndpointI endpoint : allEndpoints)
{
if(!(endpoint instanceof IceInternal.OpaqueEndpointI))
{
endpoints.add(endpoint);
}
}
//
// Filter out endpoints according to the mode of the reference.
//
switch(getMode())
{
case Reference.ModeTwoway:
case Reference.ModeOneway:
case Reference.ModeBatchOneway:
{
//
// Filter out datagram endpoints.
//
java.util.Iterator i = endpoints.iterator();
while(i.hasNext())
{
EndpointI endpoint = i.next();
if(endpoint.datagram())
{
i.remove();
}
}
break;
}
case Reference.ModeDatagram:
case Reference.ModeBatchDatagram:
{
//
// Filter out non-datagram endpoints.
//
java.util.Iterator i = endpoints.iterator();
while(i.hasNext())
{
EndpointI endpoint = i.next();
if(!endpoint.datagram())
{
i.remove();
}
}
break;
}
}
//
// Sort the endpoints according to the endpoint selection type.
//
switch(getEndpointSelection())
{
case Random:
{
java.util.Collections.shuffle(endpoints);
break;
}
case Ordered:
{
// Nothing to do.
break;
}
default:
{
assert(false);
break;
}
}
//
// If a secure connection is requested or secure overrides is
// set, remove all non-secure endpoints. Otherwise if preferSecure is set
// make secure endpoints prefered. By default make non-secure
// endpoints preferred over secure endpoints.
//
DefaultsAndOverrides overrides = getInstance().defaultsAndOverrides();
if(overrides.overrideSecure ? overrides.overrideSecureValue : getSecure())
{
java.util.Iterator i = endpoints.iterator();
while(i.hasNext())
{
EndpointI endpoint = i.next();
if(!endpoint.secure())
{
i.remove();
}
}
}
else if(getPreferSecure())
{
java.util.Collections.sort(endpoints, _preferSecureEndpointComparator);
}
else
{
java.util.Collections.sort(endpoints, _preferNonSecureEndpointComparator);
}
return endpoints.toArray(new EndpointI[endpoints.size()]);
}
protected void
createConnection(EndpointI[] allEndpoints, final GetConnectionCallback callback)
{
final EndpointI[] endpoints = filterEndpoints(allEndpoints);
if(endpoints.length == 0)
{
callback.setException(new Ice.NoEndpointException(toString()));
return;
}
//
// Finally, create the connection.
//
final OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory();
if(getCacheConnection() || endpoints.length == 1)
{
//
// Get an existing connection or create one if there's no
// existing connection to one of the given endpoints.
//
factory.create(endpoints, false, getEndpointSelection(),
new OutgoingConnectionFactory.CreateConnectionCallback()
{
@Override
public void
setConnection(Ice.ConnectionI connection, boolean compress)
{
//
// If we have a router, set the object adapter for this router
// (if any) to the new connection, so that callbacks from the
// router can be received over this new connection.
//
if(_routerInfo != null && _routerInfo.getAdapter() != null)
{
connection.setAdapter(_routerInfo.getAdapter());
}
callback.setConnection(connection, compress);
}
@Override
public void
setException(Ice.LocalException ex)
{
callback.setException(ex);
}
});
}
else
{
//
// Go through the list of endpoints and try to create the
// connection until it succeeds. This is different from just
// calling create() with the given endpoints since this might
// create a new connection even if there's an existing
// connection for one of the endpoints.
//
factory.create(new EndpointI[]{ endpoints[0] }, true, getEndpointSelection(),
new OutgoingConnectionFactory.CreateConnectionCallback()
{
@Override
public void
setConnection(Ice.ConnectionI connection, boolean compress)
{
//
// If we have a router, set the object adapter for this router
// (if any) to the new connection, so that callbacks from the
// router can be received over this new connection.
//
if(_routerInfo != null && _routerInfo.getAdapter() != null)
{
connection.setAdapter(_routerInfo.getAdapter());
}
callback.setConnection(connection, compress);
}
@Override
public void
setException(final Ice.LocalException ex)
{
if(_exception == null)
{
_exception = ex;
}
if(++_i == endpoints.length)
{
callback.setException(_exception);
return;
}
final boolean more = _i != endpoints.length - 1;
final EndpointI[] endpoint = new EndpointI[]{ endpoints[_i] };
factory.create(endpoint, more, getEndpointSelection(), this);
}
private int _i = 0;
private Ice.LocalException _exception = null;
});
}
}
static class EndpointComparator implements java.util.Comparator
{
EndpointComparator(boolean preferSecure)
{
_preferSecure = preferSecure;
}
@Override
public int
compare(EndpointI le, EndpointI re)
{
boolean ls = le.secure();
boolean rs = re.secure();
if((ls && rs) || (!ls && !rs))
{
return 0;
}
else if(!ls && rs)
{
if(_preferSecure)
{
return 1;
}
else
{
return -1;
}
}
else
{
if(_preferSecure)
{
return -1;
}
else
{
return 1;
}
}
}
private boolean _preferSecure;
}
private static EndpointComparator _preferNonSecureEndpointComparator = new EndpointComparator(false);
private static EndpointComparator _preferSecureEndpointComparator = new EndpointComparator(true);
private static EndpointI[] _emptyEndpoints = new EndpointI[0];
private EndpointI[] _endpoints;
private String _adapterId;
private LocatorInfo _locatorInfo; // Null if no router is used.
private RouterInfo _routerInfo; // Null if no router is used.
private boolean _collocationOptimized;
private boolean _cacheConnection;
private boolean _preferSecure;
private Ice.EndpointSelectionType _endpointSelection;
private int _locatorCacheTimeout;
private boolean _overrideTimeout;
private int _timeout; // Only used if _overrideTimeout == true
private String _connectionId = "";
}