internal void Invoke(ILocatorPrx l) { if (_locatorPrx == null || !_locatorPrx.Equals(l)) { _locatorPrx = l; var requestFrame = new OutgoingRequestFrame(l, _operation, _idempotent, _context, _payload); l.InvokeAsync(requestFrame).ContinueWith( task => { try { SetResult(task.Result); } catch (AggregateException ae) { Exception(ae.InnerException); } }, TaskScheduler.Current); } else { Debug.Assert(_exception != null); throw _exception; } }
public void Initialize(PluginInitializationContext context) { string address = _communicator.GetProperty($"{_name}.Address") ?? (_communicator.PreferIPv6 ? "ff15::1" : "239.255.0.1"); int port = _communicator.GetPropertyAsInt($"{_name}.Port") ?? 4061; string intf = _communicator.GetProperty($"{_name}.Interface") ?? ""; string lookupEndpoints = _communicator.GetProperty($"{_name}.Lookup") ?? ""; if (lookupEndpoints.Length == 0) { int ipVersion = _communicator.PreferIPv6 ? Network.EnableIPv6 : Network.EnableIPv4; List <string> interfaces = Network.GetInterfacesForMulticast(intf, ipVersion); lookupEndpoints = string.Join(":", interfaces.Select( intf => $"udp -h \"{address}\" -p {port} --interface \"{intf}\"")); } if (_communicator.GetProperty($"{_name}.Reply.Endpoints") == null) { _communicator.SetProperty($"{_name}.Reply.Endpoints", intf.Length == 0 ? "udp -h *" : $"udp -h \"{intf}\""); } if (_communicator.GetProperty($"{_name}.Locator.Endpoints") == null) { _communicator.SetProperty($"{_name}.Locator.AdapterId", Guid.NewGuid().ToString()); } _replyAdapter = _communicator.CreateObjectAdapter(_name + ".Reply"); _locatorAdapter = _communicator.CreateObjectAdapter(_name + ".Locator"); // We don't want those adapters to be registered with the locator so clear their locator. _replyAdapter.Locator = null; _locatorAdapter.Locator = null; var lookupPrx = ILookupPrx.Parse($"IceLocatorDiscovery/Lookup -d:{lookupEndpoints}", _communicator); lookupPrx = lookupPrx.Clone(clearRouter: false); ILocatorPrx voidLocator = _locatorAdapter.AddWithUUID(new VoidLocator(), ILocatorPrx.Factory); var lookupReplyId = new Identity(Guid.NewGuid().ToString(), ""); ILookupReplyPrx?locatorReplyPrx = _replyAdapter.CreateProxy(lookupReplyId, ILookupReplyPrx.Factory).Clone( invocationMode: InvocationMode.Datagram); _defaultLocator = _communicator.DefaultLocator; string instanceName = _communicator.GetProperty($"{_name}.InstanceName") ?? ""; var locatorId = new Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString()); _locator = new Locator(_name, lookupPrx, _communicator, instanceName, voidLocator, locatorReplyPrx); _locatorPrx = _locatorAdapter.Add(locatorId, _locator, ILocatorPrx.Factory); _communicator.DefaultLocator = _locatorPrx; _replyAdapter.Add(lookupReplyId, new LookupReply(_locator)); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
// Returns locator info for a given locator. Automatically creates the locator info if it doesn't exist yet. internal LocatorInfo?GetLocatorInfo(ILocatorPrx?locator, Encoding encoding) { if (locator == null) { return(null); } if (locator.Locator != null || locator.Encoding != encoding) { // The locator can't be located. locator = locator.Clone(clearLocator: true, encoding: encoding); } // TODO: reap unused locator info objects? lock (_locatorInfoMap) { if (!_locatorInfoMap.TryGetValue(locator, out LocatorInfo? info)) { // Rely on locator identity for the adapter table. We want to // have only one table per locator (not one per locator // proxy). var key = new LocatorKey(locator); if (!_locatorTableMap.TryGetValue(key, out LocatorTable? table)) { table = new LocatorTable(); _locatorTableMap[key] = table; } info = new LocatorInfo(locator, table, _backgroundLocatorCacheUpdates); _locatorInfoMap[locator] = info; } return(info); } }
public async ValueTask<OutgoingResponseFrame> DispatchAsync( IncomingRequestFrame incomingRequest, Current current) { ILocatorPrx? locator = null; Exception? exception = null; while (true) { // Get the locator to send the request to (this will return the void locator if no locator is found) ILocatorPrx newLocator = await GetLocatorAsync().ConfigureAwait(false); if (locator != newLocator) { var outgoingRequest = new OutgoingRequestFrame( newLocator, current.Operation, current.IsIdempotent, current.Context, incomingRequest.Payload); try { IncomingResponseFrame incomingResponse = await newLocator.InvokeAsync(outgoingRequest).ConfigureAwait(false); return new OutgoingResponseFrame(current.Protocol, current.Encoding, incomingResponse.Payload); } catch (DispatchException) { throw; } catch (NoEndpointException) { throw new ObjectNotExistException(current); } catch (ObjectAdapterDeactivatedException) { throw new ObjectNotExistException(current); } catch (CommunicatorDestroyedException) { throw new ObjectNotExistException(current); } catch (Exception ex) { lock (_mutex) { locator = newLocator; // If the current locator is equal to the one we use to send the request, // clear it and retry, this will trigger the lookup of a new locator. if (_locator == newLocator) { _locator = null; } } exception = ex; } } else { // We got the same locator after a previous failure, throw the saved exception now. Debug.Assert(exception != null); throw exception; } } }
public async ValueTask <OutgoingResponseFrame> DispatchAsync( IncomingRequestFrame incomingRequest, Current current) { ILocatorPrx?locator = null; Exception? exception = null; while (true) { // Get the locator to send the request to (this will return the void locator if no locator is found) ILocatorPrx newLocator = await GetLocatorAsync().ConfigureAwait(false); if (!newLocator.Equals(locator)) { try { return(await newLocator.ForwardAsync(false, incomingRequest).ConfigureAwait(false)); } catch (ObjectNotExistException) { throw; } catch (NoEndpointException) { throw new ObjectNotExistException(current); } catch (ObjectDisposedException) { throw new ObjectNotExistException(current); } catch (Exception ex) { lock (_mutex) { locator = newLocator; // If the current locator is equal to the one we use to send the request, // clear it and retry, this will trigger the lookup of a new locator. if (_locator == newLocator) { _locator = null; } } exception = ex; } } else { // We got the same locator after a previous failure, throw the saved exception now. Debug.Assert(exception != null); throw exception; } } }
/// <summary>Creates a clone of this proxy. The clone is identical to this proxy except for options set /// through parameters. This method returns this proxy instead of a new proxy in the event none of the options /// specified through the parameters change this proxy's options.</summary> /// <param name="prx">The source proxy.</param> /// <param name="adapterId">The adapter ID of the clone (optional).</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="collocationOptimized">Determines whether or not the clone can use collocation optimization /// (optional).</param> /// <param name="compress">Determines whether or not the clone compresses requests (optional).</param> /// <param name="connectionId">The connection ID of the clone (optional).</param> /// <param name="connectionTimeout">The connection timeout of the clone (optional).</param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpointSelection">The encoding selection policy of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="invocationMode">The invocation mode of the clone (optional).</param> /// <param name="invocationTimeout">The invocation timeout of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional). This is a simplified /// version of the invocationMode parameter.</param> /// <param name="preferSecure">Determines whether the clone prefers secure connections over non-secure /// connections (optional).</param> /// <param name="protocol">The Ice protocol of the clone (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <param name="secure">The secure option of the clone (optional).</param> /// <returns>A new proxy with the same type as this proxy.</returns> public static T Clone <T>(this T prx, string?adapterId = null, bool?cacheConnection = null, bool clearLocator = false, bool clearRouter = false, bool?collocationOptimized = null, bool?compress = null, string?connectionId = null, int?connectionTimeout = null, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, EndpointSelectionType?endpointSelection = null, IEndpoint[]?endpoints = null, Connection?fixedConnection = null, InvocationMode?invocationMode = null, int?invocationTimeout = null, ILocatorPrx?locator = null, int?locatorCacheTimeout = null, bool?oneway = null, bool?preferSecure = null, Protocol?protocol = null, IRouterPrx?router = null, bool?secure = null) where T : IObjectPrx { Reference clone = prx.IceReference.Clone(adapterId, cacheConnection, clearLocator, clearRouter, collocationOptimized, compress, connectionId, connectionTimeout, context, encoding, endpointSelection, endpoints?.Select(e => (Endpoint)e).ToArray(), facet: null, fixedConnection, identity: null, invocationMode, invocationTimeout, locator, locatorCacheTimeout, oneway, preferSecure, protocol, router, secure); // Reference.Clone never returns a new reference == to itself. return(ReferenceEquals(clone, prx.IceReference) ? prx : (T)prx.Clone(clone)); }
/// <summary>Creates a clone of this proxy, with a new identity and optionally other options. The clone /// is identical to this proxy except for its identity and other options set through parameters.</summary> /// <param name="prx">The source proxy.</param> /// <param name="identity">The identity of the clone.</param> /// <param name="factory">The proxy factory used to manufacture the clone.</param> /// <param name="adapterId">The adapter ID of the clone (optional).</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="collocationOptimized">Determines whether or not the clone can use collocation optimization /// (optional).</param> /// <param name="compress">Determines whether or not the clone compresses requests (optional).</param> /// <param name="connectionId">The connection ID of the clone (optional).</param> /// <param name="connectionTimeout">The connection timeout of the clone (optional).</param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpointSelection">The encoding selection policy of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="facet">The facet of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="invocationMode">The invocation mode of the clone (optional).</param> /// <param name="invocationTimeout">The invocation timeout of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional). This is a simplified /// version of the invocationMode parameter.</param> /// <param name="preferSecure">Determines whether the clone prefers secure connections over non-secure /// connections (optional).</param> /// <param name="protocol">The Ice protocol of the clone (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <param name="secure">The secure option of the clone (optional).</param> /// <returns>A new proxy manufactured by the proxy factory (see factory parameter).</returns> public static T Clone <T>(this IObjectPrx prx, Identity identity, ProxyFactory <T> factory, string?adapterId = null, bool?cacheConnection = null, bool clearLocator = false, bool clearRouter = false, bool?collocationOptimized = null, bool?compress = null, string?connectionId = null, int?connectionTimeout = null, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, EndpointSelectionType?endpointSelection = null, IEndpoint[]?endpoints = null, string?facet = null, Connection?fixedConnection = null, InvocationMode?invocationMode = null, int?invocationTimeout = null, ILocatorPrx?locator = null, int?locatorCacheTimeout = null, bool?oneway = null, bool?preferSecure = null, Protocol?protocol = null, IRouterPrx?router = null, bool?secure = null) where T : class, IObjectPrx { return(factory(prx.IceReference.Clone(adapterId, cacheConnection, clearLocator, clearRouter, collocationOptimized, compress, connectionId, connectionTimeout, context, encoding, endpointSelection, endpoints?.Select(e => (Endpoint)e).ToArray(), facet, fixedConnection, identity, invocationMode, invocationTimeout, locator, locatorCacheTimeout, oneway, preferSecure, protocol, router, secure))); }
internal Locator( string name, ILookupPrx lookup, Communicator communicator, string instanceName, ILocatorPrx voidLocator, ILookupReplyPrx lookupReply) { _lookup = lookup; _timeout = communicator.GetPropertyAsTimeSpan($"{name}.Timeout") ?? TimeSpan.FromMilliseconds(300); if (_timeout == System.Threading.Timeout.InfiniteTimeSpan) { _timeout = TimeSpan.FromMilliseconds(300); } _retryCount = Math.Max(communicator.GetPropertyAsInt($"{name}.RetryCount") ?? 3, 1); _retryDelay = communicator.GetPropertyAsTimeSpan($"{name}.RetryDelay") ?? TimeSpan.FromMilliseconds(2000); _traceLevel = communicator.GetPropertyAsInt($"{name}.Trace.Lookup") ?? 0; _instanceName = instanceName; _warned = false; _locator = lookup.Communicator.DefaultLocator; _voidLocator = voidLocator; // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast // datagram on each endpoint. var single = new Endpoint[1]; foreach (Endpoint endpoint in lookup.Endpoints) { // lookup's invocation mode is Datagram Debug.Assert(endpoint.Transport == Transport.UDP); single[0] = endpoint; ILookupPrx key = lookup.Clone(endpoints: single); if (endpoint["interface"] is string mcastInterface && mcastInterface.Length > 0) { Endpoint?q = lookupReply.Endpoints.FirstOrDefault(e => e.Host == mcastInterface); if (q != null) { single[0] = q; _lookups[key] = lookupReply.Clone(endpoints: single); } } if (!_lookups.ContainsKey(key)) { // Fallback: just use the given lookup reply proxy if no matching endpoint found. _lookups[key] = lookupReply; } } Debug.Assert(_lookups.Count > 0); }
public static IObjectPrx Clone(this IObjectPrx prx, string facet, string?adapterId = null, bool clearLocator = false, bool clearRouter = false, bool?collocationOptimized = null, bool?compress = null, bool?connectionCached = null, string?connectionId = null, int?connectionTimeout = null, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, EndpointSelectionType?endpointSelectionType = null, IEndpoint[]?endpoints = null, Connection?fixedConnection = null, InvocationMode?invocationMode = null, int?invocationTimeout = null, ILocatorPrx?locator = null, int?locatorCacheTimeout = null, bool?oneway = null, bool?preferSecure = null, IRouterPrx?router = null, bool?secure = null) { Reference reference = prx.IceReference.Clone( null, facet, adapterId, clearLocator, clearRouter, collocationOptimized, compress, connectionCached, connectionId, connectionTimeout, context, encoding, endpointSelectionType, endpoints, fixedConnection, invocationMode, invocationTimeout, locator, locatorCacheTimeout, oneway, preferSecure, router, secure); return(reference.Equals(prx.IceReference) ? prx : prx.Clone(reference)); }
/// <summary>Creates a clone of this proxy. The clone is identical to this proxy except for options set /// through parameters. This method returns this proxy instead of a new proxy in the event none of the options /// specified through the parameters change this proxy's options.</summary> /// <param name="prx">The source proxy.</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLabel">When set to true, the clone does not have an associated label (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="invocationInterceptors">A collection of <see cref="InvocationInterceptor"/> that will be /// executed with each invocation</param> /// <param name="invocationMode">The invocation mode of the clone (optional). Applies only to ice1 proxies. /// </param> /// <param name="invocationTimeout">The invocation timeout of the clone (optional).</param> /// <param name="label">The label of the clone (optional).</param> /// <param name="location">The location of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional).</param> /// <param name="preferExistingConnection">Determines whether or not the clone prefer using an existing /// connection.</param> /// <param name="preferNonSecure">Determines whether the clone prefers non-secure connections over secure /// connections (optional).</param> /// <param name="relative">When true, the new proxy is a relative proxy (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <returns>A new proxy with the same type as this proxy.</returns> public static T Clone <T>( this T prx, bool?cacheConnection = null, bool clearLabel = false, bool clearLocator = false, bool clearRouter = false, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, IEnumerable <Endpoint>?endpoints = null, Connection?fixedConnection = null, IEnumerable <InvocationInterceptor>?invocationInterceptors = null, InvocationMode?invocationMode = null, TimeSpan?invocationTimeout = null, object?label = null, IEnumerable <string>?location = null, ILocatorPrx?locator = null, TimeSpan?locatorCacheTimeout = null, bool?oneway = null, bool?preferExistingConnection = null, NonSecure?preferNonSecure = null, bool?relative = null, IRouterPrx?router = null) where T : IObjectPrx { Reference clone = prx.IceReference.Clone(cacheConnection, clearLabel, clearLocator, clearRouter, context, encoding, endpoints, facet: null, fixedConnection, identity: null, identityAndFacet: null, invocationInterceptors, invocationMode, invocationTimeout, label, location, locator, locatorCacheTimeout, oneway, preferExistingConnection, preferNonSecure, relative, router); // Reference.Clone never returns a new reference == to itself. return(ReferenceEquals(clone, prx.IceReference) ? prx : (T)prx.Clone(clone)); }
internal Locator( string name, ILookupPrx lookup, Communicator communicator, string instanceName, ILocatorPrx voidLocator, ILookupReplyPrx lookupReply) { _lookup = lookup; _timeout = communicator.GetPropertyAsInt($"{name}.Timeout") ?? 300; if (_timeout < 0) { _timeout = 300; } _retryCount = Math.Max(communicator.GetPropertyAsInt($"{name}.RetryCount") ?? 3, 1); _retryDelay = Math.Max(communicator.GetPropertyAsInt($"{name}.RetryDelay") ?? 2000, 0); _traceLevel = communicator.GetPropertyAsInt($"{name}.Trace.Lookup") ?? 0; _instanceName = instanceName; _warned = false; _locator = lookup.Communicator.DefaultLocator; _voidLocator = voidLocator; // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast // datagram on each endpoint. var single = new Endpoint[1]; foreach (UdpEndpoint endpoint in lookup.Endpoints.Cast <UdpEndpoint>()) { single[0] = endpoint; ILookupPrx key = lookup.Clone(endpoints: single); if (endpoint.McastInterface.Length > 0) { IPEndpoint?q = lookupReply.Endpoints.Cast <IPEndpoint>().FirstOrDefault( e => e is IPEndpoint ipEndpoint && ipEndpoint.Host.Equals(endpoint.McastInterface)); if (q != null) { single[0] = q; _lookups[key] = lookupReply.Clone(endpoints: single); } } if (!_lookups.ContainsKey(key)) { // Fallback: just use the given lookup reply proxy if no matching endpoint found. _lookups[key] = lookupReply; } } Debug.Assert(_lookups.Count > 0); }
/// <summary>Creates a clone of this proxy, with a new identity and optionally other options. The clone /// is identical to this proxy except for its identity and other options set through parameters.</summary> /// <param name="prx">The source proxy.</param> /// <param name="factory">The proxy factory used to manufacture the clone.</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLabel">When set to true, the clone does not have an associated label (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="facet">The facet of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="identity">The identity of the clone.</param> /// <param name="identityAndFacet">A relative URI string [category/]identity[#facet].</param> /// <param name="invocationInterceptors">A collection of <see cref="InvocationInterceptor"/> that will be /// executed with each invocation</param> /// <param name="invocationMode">The invocation mode of the clone (optional). Applies only to ice1 proxies. /// </param> /// <param name="invocationTimeout">The invocation timeout of the clone (optional).</param> /// <param name="label">The label of the clone (optional).</param> /// <param name="location">The location of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional).</param> /// <param name="preferExistingConnection">Determines whether or not the clone prefer using an existing /// connection.</param> /// <param name="preferNonSecure">Determines whether the clone prefers non-secure connections over secure /// connections (optional).</param> /// <param name="relative">When true, the new proxy is a relative proxy (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <returns>A new proxy manufactured by the proxy factory (see factory parameter).</returns> public static T Clone <T>( this IObjectPrx prx, ProxyFactory <T> factory, bool?cacheConnection = null, bool clearLabel = false, bool clearLocator = false, bool clearRouter = false, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, IEnumerable <Endpoint>?endpoints = null, string?facet = null, Connection?fixedConnection = null, Identity?identity = null, string?identityAndFacet = null, IEnumerable <InvocationInterceptor>?invocationInterceptors = null, InvocationMode?invocationMode = null, TimeSpan?invocationTimeout = null, object?label = null, IEnumerable <string>?location = null, ILocatorPrx?locator = null, TimeSpan?locatorCacheTimeout = null, bool?oneway = null, bool?preferExistingConnection = null, NonSecure?preferNonSecure = null, bool?relative = null, IRouterPrx?router = null) where T : class, IObjectPrx => factory(prx.IceReference.Clone(cacheConnection, clearLabel, clearLocator, clearRouter, context, encoding, endpoints, facet, fixedConnection, identity, identityAndFacet, invocationInterceptors, invocationMode, invocationTimeout, label, location, locator, locatorCacheTimeout, oneway, preferExistingConnection, preferNonSecure, relative, router));
/// <summary>Creates a clone of this proxy, with a new facet and optionally other options. The clone is /// identical to this proxy except for its facet and other options set through parameters.</summary> /// <param name="prx">The source proxy.</param> /// <param name="facet">The facet of the clone.</param> /// <param name="factory">The proxy factory used to manufacture the clone.</param> /// <param name="adapterId">The adapter ID of the clone (optional).</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="compress">Determines whether or not the clone compresses requests (optional).</param> /// <param name="connectionId">The connection ID of the clone (optional).</param> /// <param name="connectionTimeout">The connection timeout of the clone (optional).</param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpointSelection">The encoding selection policy of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="invocationMode">The invocation mode of the clone (optional).</param> /// <param name="invocationTimeout">The invocation timeout of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional). This is a simplified /// version of the invocationMode parameter.</param> /// <param name="preferNonSecure">Determines whether the clone prefers non-secure connections over secure /// connections (optional).</param> /// <param name="protocol">The Ice protocol of the clone (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <returns>A new proxy manufactured by the proxy factory (see factory parameter).</returns> public static T Clone <T>(this IObjectPrx prx, string facet, ProxyFactory <T> factory, string?adapterId = null, bool?cacheConnection = null, bool clearLocator = false, bool clearRouter = false, bool?compress = null, string?connectionId = null, int?connectionTimeout = null, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, EndpointSelectionType?endpointSelection = null, IEnumerable <Endpoint>?endpoints = null, Connection?fixedConnection = null, InvocationMode?invocationMode = null, int?invocationTimeout = null, ILocatorPrx?locator = null, TimeSpan?locatorCacheTimeout = null, bool?oneway = null, bool?preferNonSecure = null, Protocol?protocol = null, IRouterPrx?router = null) where T : class, IObjectPrx { return(factory(prx.IceReference.Clone(adapterId, cacheConnection, clearLocator, clearRouter, compress, connectionId, connectionTimeout, context, encoding, endpointSelection, endpoints, facet, fixedConnection, identity: null, invocationMode, invocationTimeout, locator, locatorCacheTimeout, oneway, preferNonSecure, protocol, router))); }
destroy() { if (_replyAdapter != null) { _replyAdapter.Destroy(); } if (_locatorAdapter != null) { _locatorAdapter.Destroy(); } ILocatorPrx?defaultLocator = _communicator.getDefaultLocator(); if (defaultLocator != null && defaultLocator.Equals(_locatorPrx)) { // Restore original default locator proxy, if the user didn't change it in the meantime _communicator.setDefaultLocator(_defaultLocator); } }
/// <summary>Creates a clone of this proxy. The clone is identical to this proxy except for options set /// through parameters. This method returns this proxy instead of a new proxy in the event none of the options /// specified through the parameters change this proxy's options.</summary> /// <param name="prx">The source proxy.</param> /// <param name="adapterId">The adapter ID of the clone (optional).</param> /// <param name="cacheConnection">Determines whether or not the clone caches its connection (optional).</param> /// <param name="clearLocator">When set to true, the clone does not have an associated locator proxy (optional). /// </param> /// <param name="clearRouter">When set to true, the clone does not have an associated router proxy (optional). /// </param> /// <param name="connectionId">The connection ID of the clone (optional).</param> /// <param name="context">The context of the clone (optional).</param> /// <param name="encoding">The encoding of the clone (optional).</param> /// <param name="endpointSelection">The encoding selection policy of the clone (optional).</param> /// <param name="endpoints">The endpoints of the clone (optional).</param> /// <param name="fixedConnection">The connection of the clone (optional). When specified, the clone is a fixed /// proxy. You can clone a non-fixed proxy into a fixed proxy but not vice-versa.</param> /// <param name="invocationMode">The invocation mode of the clone (optional).</param> /// <param name="locator">The locator proxy of the clone (optional).</param> /// <param name="locatorCacheTimeout">The locator cache timeout of the clone (optional).</param> /// <param name="oneway">Determines whether the clone is oneway or twoway (optional). This is a simplified /// version of the invocationMode parameter.</param> /// <param name="preferNonSecure">Determines whether the clone prefers non-secure connections over secure /// connections (optional).</param> /// <param name="router">The router proxy of the clone (optional).</param> /// <returns>A new proxy with the same type as this proxy.</returns> public static T Clone <T>( this T prx, string?adapterId = null, bool?cacheConnection = null, bool clearLocator = false, bool clearRouter = false, string?connectionId = null, IReadOnlyDictionary <string, string>?context = null, Encoding?encoding = null, EndpointSelectionType?endpointSelection = null, IEnumerable <Endpoint>?endpoints = null, Connection?fixedConnection = null, InvocationMode?invocationMode = null, ILocatorPrx?locator = null, TimeSpan?locatorCacheTimeout = null, bool?oneway = null, bool?preferNonSecure = null, IRouterPrx?router = null) where T : IObjectPrx { Reference clone = prx.IceReference.Clone(adapterId, cacheConnection, clearLocator, clearRouter, connectionId, context, encoding, endpointSelection, endpoints, facet: null, fixedConnection, identity: null, identityAndFacet: null, invocationMode, locator, locatorCacheTimeout, oneway, preferNonSecure, router); // Reference.Clone never returns a new reference == to itself. return(ReferenceEquals(clone, prx.IceReference) ? prx : (T)prx.Clone(clone)); }
internal async Task Invoke(ILocatorPrx l) { if (_locatorPrx == null || !_locatorPrx.Equals(l)) { _locatorPrx = l; var requestFrame = new OutgoingRequestFrame(l, _current.Operation, _current.IsIdempotent, _current.Context, _payload); try { SetResult(await l.InvokeAsync(requestFrame).ConfigureAwait(false)); } catch (Exception ex) { Exception(ex); } } else { Debug.Assert(_exception != null); throw _exception; } }
public void Initialize(PluginInitializationContext context) { const string defaultIPv4Endpoint = "udp -h 239.255.0.1 -p 4061"; const string defaultIPv6Endpoint = "udp -h \"ff15::1\" -p 4061"; string?lookupEndpoints = _communicator.GetProperty($"{_name}.Lookup"); if (lookupEndpoints == null) { List <string> endpoints = new (); List <string> ipv4Interfaces = Network.GetInterfacesForMulticast("0.0.0.0", Network.EnableIPv4); List <string> ipv6Interfaces = Network.GetInterfacesForMulticast("::0", Network.EnableIPv6); endpoints.AddRange(ipv4Interfaces.Select(i => $"{defaultIPv4Endpoint} --interface \"{i}\"")); endpoints.AddRange(ipv6Interfaces.Select(i => $"{defaultIPv6Endpoint} --interface \"{i}\"")); lookupEndpoints = string.Join(":", endpoints); } if (_communicator.GetProperty($"{_name}.Reply.Endpoints") == null) { _communicator.SetProperty($"{_name}.Reply.Endpoints", "udp -h \"::0\" -p 0"); } _communicator.SetProperty($"{_name}.Reply.ProxyOptions", "-d"); if (_communicator.GetProperty($"{_name}.Locator.Endpoints") == null) { _communicator.SetProperty($"{_name}.Locator.AdapterId", Guid.NewGuid().ToString()); } _replyAdapter = _communicator.CreateObjectAdapter(_name + ".Reply"); _locatorAdapter = _communicator.CreateObjectAdapter(_name + ".Locator"); // We don't want those adapters to be registered with the locator so clear their locator. _replyAdapter.Locator = null; _locatorAdapter.Locator = null; var lookupPrx = ILookupPrx.Parse($"IceLocatorDiscovery/Lookup -d:{lookupEndpoints}", _communicator); lookupPrx = lookupPrx.Clone(clearRouter: false); var lookupReplyId = new Identity(Guid.NewGuid().ToString(), ""); ILookupReplyPrx locatorReplyPrx = _replyAdapter.CreateProxy(lookupReplyId, ILookupReplyPrx.Factory); Debug.Assert(locatorReplyPrx.InvocationMode == InvocationMode.Datagram); _defaultLocator = _communicator.DefaultLocator; string instanceName = _communicator.GetProperty($"{_name}.InstanceName") ?? ""; var locatorId = new Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString()); _locatorServant = new Locator(_name, lookupPrx, _communicator, instanceName, locatorReplyPrx); _locator = _locatorAdapter.Add(locatorId, _locatorServant, ILocatorPrx.Factory); _communicator.DefaultLocator = _locator; _replyAdapter.Add(lookupReplyId, new LookupReply(_locatorServant)); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
invoke(ILocatorPrx?locator, Request?request) { lock (this) { if (request != null && _locator != null && _locator != locator) { request.invoke(_locator); } else if (request != null && IceInternal.Time.currentMonotonicTimeMillis() < _nextRetry) { request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires } else { _locator = null; if (request != null) { _pendingRequests.Add(request); } if (!_pending) // No request in progress { _pending = true; _pendingRetryCount = _retryCount; _failureCount = 0; try { if (_traceLevel > 1) { StringBuilder s = new StringBuilder("looking up locator:\nlookup = "); s.Append(_lookup); if (_instanceName.Length == 0) { s.Append("\ninstance name = ").Append(_instanceName); } _lookup.Communicator.Logger.trace("Lookup", s.ToString()); } foreach (var l in _lookups) { l.Key.FindLocatorAsync(_instanceName, l.Value).ContinueWith(t => { try { t.Wait(); } catch (AggregateException ex) { exception(ex.InnerException); } }, l.Key.Scheduler); // Send multicast request. } _timer.schedule(this, _timeout); } catch (LocalException ex) { if (_traceLevel > 0) { StringBuilder s = new StringBuilder("locator lookup failed:\nlookup = "); s.Append(_lookup); if (_instanceName.Length == 0) { s.Append("\ninstance name = ").Append(_instanceName); } s.Append("\n").Append(ex); _lookup.Communicator.Logger.trace("Lookup", s.ToString()); } foreach (Request req in _pendingRequests) { req.invoke(_voidLocator); } _pendingRequests.Clear(); _pendingRetryCount = 0; _pending = false; } } } } }
Invoke(ILocatorPrx? locator, Request? request) { lock (this) { if (request != null && _locator != null && _locator != locator) { _ = request.Invoke(_locator); } else if (request != null && Time.CurrentMonotonicTimeMillis() < _nextRetry) { _ = request.Invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires } else { _locator = null; if (request != null) { _pendingRequests.Add(request); } if (!_pending) // No request in progress { _pending = true; _pendingRetryCount = _retryCount; _failureCount = 0; try { if (_traceLevel > 1) { var s = new StringBuilder("looking up locator:\nlookup = "); s.Append(_lookup); if (_instanceName.Length == 0) { s.Append("\ninstance name = ").Append(_instanceName); } _lookup.Communicator.Logger.Trace("Lookup", s.ToString()); } foreach (KeyValuePair<ILookupPrx, ILookupReplyPrx?> l in _lookups) { _ = FindLocator(l.Key, l.Value!); // Send multicast request. } _timer.Schedule(this, _timeout); } catch (System.Exception ex) { if (_traceLevel > 0) { var s = new StringBuilder("locator lookup failed:\nlookup = "); s.Append(_lookup); if (_instanceName.Length == 0) { s.Append("\ninstance name = ").Append(_instanceName); } s.Append("\n").Append(ex); _lookup.Communicator.Logger.Trace("Lookup", s.ToString()); } foreach (Request req in _pendingRequests) { _ = req.Invoke(_voidLocator); } _pendingRequests.Clear(); _pendingRetryCount = 0; _pending = false; } } } } }
public void Initialize(PluginInitializationContext context) { bool ipv4 = _communicator.GetPropertyAsBool("Ice.IPv4") ?? true; bool preferIPv6 = _communicator.GetPropertyAsBool("Ice.PreferIPv6Address") ?? false; string address; if (ipv4 && !preferIPv6) { address = _communicator.GetProperty("IceDiscovery.Address") ?? "239.255.0.1"; } else { address = _communicator.GetProperty("IceDiscovery.Address") ?? "ff15::1"; } int port = _communicator.GetPropertyAsInt("IceDiscovery.Port") ?? 4061; string intf = _communicator.GetProperty("IceDiscovery.Interface") ?? ""; if (_communicator.GetProperty("IceDiscovery.Multicast.Endpoints") == null) { if (intf.Length > 0) { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"udp -h \"{address}\" -p {port} --interface \"{intf}\""); } else { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"udp -h \"{address}\" -p {port}"); } } string lookupEndpoints = _communicator.GetProperty("IceDiscovery.Lookup") ?? ""; if (lookupEndpoints.Length == 0) { int ipVersion = ipv4 && !preferIPv6 ? Network.EnableIPv4 : Network.EnableIPv6; List <string> interfaces = Network.GetInterfacesForMulticast(intf, ipVersion); foreach (string p in interfaces) { if (p != interfaces[0]) { lookupEndpoints += ":"; } lookupEndpoints += $"udp -h \"{address}\" -p {port} --interface \"{p}\""; } } if (_communicator.GetProperty("IceDiscovery.Reply.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Reply.Endpoints", intf.Length == 0 ? "udp -h *" : $"udp -h \"{intf}\""); } if (_communicator.GetProperty("IceDiscovery.Locator.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); } _multicastAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Multicast"); _replyAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Reply"); _locatorAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Locator"); // Setup locator registry. var locatorRegistry = new LocatorRegistry(); ILocatorRegistryPrx locatorRegistryPrx = _locatorAdapter.AddWithUUID(locatorRegistry, ILocatorRegistryPrx.Factory); ILookupPrx lookupPrx = ILookupPrx.Parse($"IceDiscovery/Lookup -d:{lookupEndpoints}", _communicator).Clone(clearRouter: true); // Add lookup Ice object var lookup = new Lookup(locatorRegistry, lookupPrx, _communicator, _replyAdapter); _multicastAdapter.Add("IceDiscovery/Lookup", lookup); // Setup locator on the communicator. _locator = _locatorAdapter.AddWithUUID(new Locator(lookup, locatorRegistryPrx), ILocatorPrx.Factory); _defaultLocator = _communicator.DefaultLocator; _communicator.DefaultLocator = _locator; _multicastAdapter.Activate(); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
internal void FoundLocator(ILocatorPrx?locator) { lock (_mutex) { if (locator == null) { if (_traceLevel > 2) { _lookup.Communicator.Logger.Trace("Lookup", "ignoring locator reply: (null locator)"); } return; } if (_instanceName.Length > 0 && !locator.Identity.Category.Equals(_instanceName)) { if (_traceLevel > 2) { _lookup.Communicator.Logger.Trace("Lookup", @$ "ignoring locator reply: instance name doesn't match\nexpected = {_instanceName } received = {locator.Identity.Category}"); } return; } // If we already have a locator assigned, ensure the given locator has the same identity, otherwise // ignore it. if (_locator != null && !locator.Identity.Category.Equals(_locator.Identity.Category)) { if (!_warned) { _warned = true; // Only warn once var s = new StringBuilder(); s.Append("received Ice locator with different instance name:\n") .Append("using = `").Append(_locator.Identity.Category).Append("'\n") .Append("received = `").Append(locator.Identity.Category).Append("'\n") .Append("This is typically the case if multiple Ice locators with different ") .Append("instance names are deployed and the property `IceLocatorDiscovery.InstanceName' ") .Append("is not set."); locator.Communicator.Logger.Warning(s.ToString()); } return; } if (_traceLevel > 0) { var s = new StringBuilder("locator lookup succeeded:\nlocator = "); s.Append(locator); if (_instanceName.Length > 0) { s.Append("\ninstance name = ").Append(_instanceName); } _lookup.Communicator.Logger.Trace("Lookup", s.ToString()); } if (_locator == null) { _locator = locator; if (_instanceName.Length == 0) { _instanceName = _locator.Identity.Category; // Stick to the first locator } Debug.Assert(_completionSource != null); _completionSource.TrySetResult(locator); } else { // We found another locator replica, append its endpoints to the current locator proxy endpoints, // while eliminating duplicates. _locator = _locator.Clone(endpoints: _locator.Endpoints.Concat(locator.Endpoints).Distinct()); } } }
public void FoundLocator(ILocatorPrx?locator, Current current) => _locator.FoundLocator(locator);
foundLocator(ILocatorPrx locator) { lock (this) { if (locator == null || (_instanceName.Length > 0 && !locator.Identity.category.Equals(_instanceName))) { if (_traceLevel > 2) { StringBuilder s = new StringBuilder("ignoring locator reply: instance name doesn't match\n"); s.Append("expected = ").Append(_instanceName); s.Append("received = ").Append(locator.Identity.category); _lookup.Communicator.Logger.trace("Lookup", s.ToString()); } return; } // // If we already have a locator assigned, ensure the given locator // has the same identity, otherwise ignore it. // if (_pendingRequests.Count > 0 && _locator != null && !locator.Identity.category.Equals(_locator.Identity.category)) { if (!_warned) { _warned = true; // Only warn once locator.Communicator.Logger.warning( "received Ice locator with different instance name:\n" + "using = `" + _locator.Identity.category + "'\n" + "received = `" + locator.Identity.category + "'\n" + "This is typically the case if multiple Ice locators with different " + "instance names are deployed and the property `IceLocatorDiscovery.InstanceName'" + "is not set."); } return; } if (_pending) // No need to continue, we found a locator { _timer.cancel(this); _pendingRetryCount = 0; _pending = false; } if (_traceLevel > 0) { StringBuilder s = new StringBuilder("locator lookup succeeded:\nlocator = "); s.Append(locator); if (_instanceName.Length == 0) { s.Append("\ninstance name = ").Append(_instanceName); } _lookup.Communicator.Logger.trace("Lookup", s.ToString()); } ILocatorPrx?l = null; if (_pendingRequests.Count == 0) { _locators.TryGetValue(locator.Identity.category, out _locator); } else { l = _locator; } if (l != null) { // // We found another locator replica, append its endpoints to the // current locator proxy endpoints. // List <Endpoint> newEndpoints = new List <Endpoint>(l.Endpoints); foreach (Endpoint p in locator.Endpoints) { // // Only add endpoints if not already in the locator proxy endpoints // bool found = false; foreach (Endpoint q in newEndpoints) { if (p.Equals(q)) { found = true; break; } } if (!found) { newEndpoints.Add(p); } } l = l.Clone(endpoints: newEndpoints.ToArray()); } else { l = locator; } if (_pendingRequests.Count == 0) { _locators[locator.Identity.category] = l; Monitor.Pulse(this); } else { _locator = l; if (_instanceName.Length == 0) { _instanceName = _locator.Identity.category; // Stick to the first locator } // // Send pending requests if any. // foreach (Request req in _pendingRequests) { req.invoke(_locator); } _pendingRequests.Clear(); } } }
public void Initialize(PluginInitializationContext context) { const string defaultIPv4Endpoint = "udp -h 239.255.0.1 -p 4061"; const string defaultIPv6Endpoint = "udp -h \"ff15::1\" -p 4061"; if (_communicator.GetProperty("IceDiscovery.Multicast.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"{defaultIPv4Endpoint}:{defaultIPv6Endpoint}"); } string?lookupEndpoints = _communicator.GetProperty("IceDiscovery.Lookup"); if (lookupEndpoints == null) { List <string> endpoints = new (); List <string> ipv4Interfaces = Network.GetInterfacesForMulticast("0.0.0.0", Network.EnableIPv4); List <string> ipv6Interfaces = Network.GetInterfacesForMulticast("::0", Network.EnableIPv6); endpoints.AddRange(ipv4Interfaces.Select(i => $"{defaultIPv4Endpoint} --interface \"{i}\"")); endpoints.AddRange(ipv6Interfaces.Select(i => $"{defaultIPv6Endpoint} --interface \"{i}\"")); lookupEndpoints = string.Join(":", endpoints); } if (_communicator.GetProperty("IceDiscovery.Reply.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Reply.Endpoints", "udp -h \"::0\" -p 0"); } if (_communicator.GetProperty("IceDiscovery.Locator.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); } _multicastAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Multicast"); _replyAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Reply"); _locatorAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Locator"); // Setup locator registry. var locatorRegistryServant = new LocatorRegistry(_communicator); ILocatorRegistryPrx locatorRegistry = _locatorAdapter.AddWithUUID(locatorRegistryServant, ILocatorRegistryPrx.Factory); ILookupPrx lookup = ILookupPrx.Parse($"IceDiscovery/Lookup -d:{lookupEndpoints}", _communicator).Clone(clearRouter: true); // Add lookup Ice object var lookupServant = new Lookup(locatorRegistryServant, _communicator); _multicastAdapter.Add("IceDiscovery/Lookup", lookupServant); // Setup locator on the communicator. _locator = _locatorAdapter.AddWithUUID(new Locator(locatorRegistry, lookup, _replyAdapter), ILocatorPrx.Factory); _defaultLocator = _communicator.DefaultLocator; _communicator.DefaultLocator = _locator; _multicastAdapter.Activate(); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
public static IMyClassPrx Run(TestHelper helper) { Communicator?communicator = helper.Communicator(); TestHelper.Assert(communicator != null); System.IO.TextWriter output = helper.GetWriter(); output.Write("testing proxy parsing... "); output.Flush(); // ice1 proxies string[] ice1ProxyArray = { "ice -t:tcp -p 10000", "ice+tcp:ssl -p 10000", }; // ice2 proxies string[] ice2ProxyArray = { "ice+tcp://host.zeroc.com/identity#facet", "ice+tcp://host.zeroc.com:1000/category/name", "ice+tcp://host.zeroc.com/category/name%20with%20space", "ice+ws://host.zeroc.com//identity", "ice+ws://host.zeroc.com//identity?alt-endpoint=host2.zeroc.com", "ice+ws://host.zeroc.com//identity?alt-endpoint=host2.zeroc.com:10000", "ice+tcp://[::1]:10000/identity?alt-endpoint=host1:10000,host2,host3,host4", "ice+ssl://[::1]:10000/identity?alt-endpoint=host1:10000&alt-endpoint=host2,host3&alt-endpoint=[::2]", "ice:location//identity#facet", "ice+tcp://host.zeroc.com//identity", "ice+tcp://host.zeroc.com:/identity", // another syntax for empty port "ice+universal://com.zeroc.ice/identity?transport=iaps&option=a,b%2Cb,c&option=d", "ice+universal://host.zeroc.com/identity?transport=100", "ice+universal://[::ab:cd:ef:00]/identity?transport=bt", // leading :: to make the address IPv6-like "ice+ws://host.zeroc.com/identity?resource=/foo%2Fbar?/xyz", "ice+universal://host.zeroc.com:10000/identity?transport=tcp", "ice+universal://host.zeroc.com/identity?transport=ws&option=/foo%2520/bar", "ice:tcp -p 10000", // a valid URI }; // ice3 proxies string[] ice3ProxyArray = { "ice+universal://host.zeroc.com/identity?transport=ws&option=/foo%2520/bar&protocol=3" }; foreach (string str in ice1ProxyArray) { var prx = IObjectPrx.Parse(str, communicator); TestHelper.Assert(prx.Protocol == Protocol.Ice1); // output.WriteLine($"{str} = {prx}"); var prx2 = IObjectPrx.Parse(prx.ToString() !, communicator); TestHelper.Assert(prx.Equals(prx2)); // round-trip works } foreach (string str in ice2ProxyArray) { var prx = IObjectPrx.Parse(str, communicator); TestHelper.Assert(prx.Protocol == Protocol.Ice2); // output.WriteLine($"{str} = {prx}"); var prx2 = IObjectPrx.Parse(prx.ToString() !, communicator); TestHelper.Assert(prx.Equals(prx2)); // round-trip works } foreach (string str in ice3ProxyArray) { var prx = IObjectPrx.Parse(str, communicator); TestHelper.Assert(prx.Protocol == (Protocol)3); // output.WriteLine($"{str} = {prx}"); var prx2 = IObjectPrx.Parse(prx.ToString() !, communicator); TestHelper.Assert(prx.Equals(prx2)); // round-trip works } string[] badProxyArray = { "ice+tcp://host.zeroc.com:foo", // missing host "ice+tcp:identity?protocol=invalid", // invalid protocol "ice+universal://host.zeroc.com", // missing transport "ice+universal://host.zeroc.com?transport=100&protocol=ice1", // invalid protocol "ice://*****:*****@adapter test", "id -f \"facet x", "id -f \'facet x", "test -f facet@test @test", "test -p 2.0", "test:tcp@adapterId", "test: :tcp", "id:opaque -t 99 -v abcd -x abc", // invalid x option "id:opaque", // missing -t and -v "id:opaque -t 1 -t 1 -v abcd", // repeated -t "id:opaque -t 1 -v abcd -v abcd", "id:opaque -v abcd", "id:opaque -t 1", "id:opaque -t -v abcd", "id:opaque -t 1 -v", "id:opaque -t x -v abcd", "id:opaque -t -1 -v abcd", // -t must be >= 0 "id:opaque -t 99 -v x?c", // invalid char in v "id:opaque -t 99 -v xc", // invalid length for base64 input }; foreach (string str in badProxyArray) { try { _ = IObjectPrx.Parse(str, communicator); TestHelper.Assert(false); } catch (FormatException) { // expected } } string rf = helper.GetTestProxy("test"); var baseProxy = IObjectPrx.Parse(rf, communicator); TestHelper.Assert(baseProxy != null); var b1 = IObjectPrx.Parse("ice:test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.AdapterId.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse("ice:test ", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse(" ice:test ", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse(" ice:test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse("test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.AdapterId.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse("test ", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse(" test ", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse(" test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); // The following tests are only relevant to the ice1 format b1 = IObjectPrx.Parse("'test -f facet'", communicator); TestHelper.Assert(b1.Identity.Name == "test -f facet" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); try { b1 = IObjectPrx.Parse("\"test -f facet'", communicator); TestHelper.Assert(false); } catch (FormatException) { } b1 = IObjectPrx.Parse("\"test -f facet\"", communicator); TestHelper.Assert(b1.Identity.Name == "test -f facet" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse("\"test -f facet@test\"", communicator); TestHelper.Assert(b1.Identity.Name == "test -f facet@test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); b1 = IObjectPrx.Parse("\"test -f facet@test @test\"", communicator); TestHelper.Assert(b1.Identity.Name == "test -f facet@test @test" && b1.Identity.Category.Length == 0 && b1.Facet.Length == 0); try { b1 = IObjectPrx.Parse("test test", communicator); TestHelper.Assert(false); } catch (FormatException) { } b1 = IObjectPrx.Parse("test\\040test", communicator); TestHelper.Assert(b1.Identity.Name == "test test" && b1.Identity.Category.Length == 0); try { b1 = IObjectPrx.Parse("test\\777", communicator); TestHelper.Assert(false); } catch (FormatException) { } b1 = IObjectPrx.Parse("test\\40test", communicator); TestHelper.Assert(b1.Identity.Name == "test test"); // Test some octal and hex corner cases. b1 = IObjectPrx.Parse("test\\4test", communicator); TestHelper.Assert(b1.Identity.Name == "test\u0004test"); b1 = IObjectPrx.Parse("test\\04test", communicator); TestHelper.Assert(b1.Identity.Name == "test\u0004test"); b1 = IObjectPrx.Parse("test\\004test", communicator); TestHelper.Assert(b1.Identity.Name == "test\u0004test"); b1 = IObjectPrx.Parse("test\\1114test", communicator); TestHelper.Assert(b1.Identity.Name == "test\u00494test"); b1 = IObjectPrx.Parse("test\\b\\f\\n\\r\\t\\'\\\"\\\\test", communicator); TestHelper.Assert(b1.Identity.Name == "test\b\f\n\r\t\'\"\\test" && b1.Identity.Category.Length == 0); // End of ice1 format-only tests b1 = IObjectPrx.Parse("ice:category/test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("ice+tcp://host:10000/test?source-address=::1", communicator); TestHelper.Assert(b1.Equals(IObjectPrx.Parse(b1.ToString() !, communicator))); b1 = IObjectPrx.Parse("ice:adapter//test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("ice:adapter/category/test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("ice:adapter:tcp/category/test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter:tcp")); // preferred syntax with escape: TestHelper.Assert(b1.Equals(IObjectPrx.Parse("ice:adapter%3Atcp/category/test", communicator))); b1 = IObjectPrx.Parse("category/test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("test:tcp -h host -p 10000 --sourceAddress \"::1\"", communicator); TestHelper.Assert(b1.Equals(IObjectPrx.Parse(b1.ToString() !, communicator))); b1 = IObjectPrx.Parse( "test:udp -h host -p 10000 --sourceAddress \"::1\" --interface \"0:0:0:0:0:0:0:1%lo\"", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("test@adapter", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("category/test@adapter", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("category/test@adapter:tcp", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter:tcp")); // The following tests are only for the ice1 format: b1 = IObjectPrx.Parse("'category 1/test'@adapter", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category 1" && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("'category/test 1'@adapter", communicator); TestHelper.Assert(b1.Identity.Name == "test 1" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("'category/test'@'adapter 1'", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category" && b1.AdapterId.Equals("adapter 1")); b1 = IObjectPrx.Parse("\"category \\/test@foo/test\"@adapter", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category /test@foo" && b1.AdapterId.Equals("adapter")); b1 = IObjectPrx.Parse("\"category \\/test@foo/test\"@\"adapter:tcp\"", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category == "category /test@foo" && b1.AdapterId.Equals("adapter:tcp")); // End of ice1 format-only tests. b1 = IObjectPrx.Parse("ice:id#facet", communicator); TestHelper.Assert(b1.Identity.Name == "id" && b1.Identity.Category.Length == 0 && b1.Facet == "facet"); b1 = IObjectPrx.Parse("ice:id#facet%20x", communicator); TestHelper.Assert(b1.Identity.Name == "id" && b1.Identity.Category.Length == 0 && b1.Facet == "facet x"); b1 = IObjectPrx.Parse("id -f facet", communicator); TestHelper.Assert(b1.Identity.Name == "id" && b1.Identity.Category.Length == 0 && b1.Facet == "facet"); b1 = IObjectPrx.Parse("id -f 'facet x'", communicator); TestHelper.Assert(b1.Identity.Name == "id" && b1.Identity.Category.Length == 0 && b1.Facet == "facet x"); // The following tests are only for the ice1 format: b1 = IObjectPrx.Parse("id -f \"facet x\"", communicator); TestHelper.Assert(b1.Identity.Name == "id" && b1.Identity.Category.Length == 0 && b1.Facet == "facet x"); b1 = IObjectPrx.Parse("test -f facet:tcp", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet == "facet" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("test -f \"facet:tcp\"", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet == "facet:tcp" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("test -f facet@test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet == "facet" && b1.AdapterId.Equals("test")); b1 = IObjectPrx.Parse("test -f 'facet@test'", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet == "facet@test" && b1.AdapterId.Length == 0); b1 = IObjectPrx.Parse("test -f 'facet@test'@test", communicator); TestHelper.Assert(b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.Facet == "facet@test" && b1.AdapterId.Equals("test")); // End of ice1 format-only tests. b1 = IObjectPrx.Parse("ice:test", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.Twoway); TestHelper.Assert(!b1.IsOneway); b1 = IObjectPrx.Parse("test", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.Twoway); TestHelper.Assert(!b1.IsOneway); b1 = IObjectPrx.Parse("test -t", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.Twoway); b1 = IObjectPrx.Parse("test -o", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.Oneway); b1 = IObjectPrx.Parse("test -O", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.BatchOneway); b1 = IObjectPrx.Parse("test -d", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.Datagram); b1 = IObjectPrx.Parse("test -D", communicator); TestHelper.Assert(b1.InvocationMode == InvocationMode.BatchDatagram); b1 = IObjectPrx.Parse("ice:test", communicator); TestHelper.Assert(b1.Protocol == Protocol.Ice2 && b1.Encoding == Encoding.V2_0); b1 = IObjectPrx.Parse("test", communicator); TestHelper.Assert(b1.Protocol == Protocol.Ice1 && b1.Encoding == Encoding.V1_1); b1 = IObjectPrx.Parse("ice:test?encoding=6.5", communicator); TestHelper.Assert(b1.Encoding.Major == 6 && b1.Encoding.Minor == 5); b1 = IObjectPrx.Parse("test -e 6.5", communicator); TestHelper.Assert(b1.Encoding.Major == 6 && b1.Encoding.Minor == 5); b1 = IObjectPrx.Parse("ice:test?encoding=2.1&protocol=6", communicator); TestHelper.Assert(b1.Protocol == (Protocol)6 && b1.Encoding.Major == 2 && b1.Encoding.Minor == 1); // Test invalid endpoint syntax // TODO: why are we testing this here? try { communicator.CreateObjectAdapterWithEndpoints("BadAdapter", " : "); TestHelper.Assert(false); } catch (FormatException) { } try { communicator.CreateObjectAdapterWithEndpoints("BadAdapter", "tcp: "); TestHelper.Assert(false); } catch (FormatException) { } try { communicator.CreateObjectAdapterWithEndpoints("BadAdapter", ":tcp"); TestHelper.Assert(false); } catch (FormatException) { } // Test for bug ICE-5543: escaped escapes in Identity.Parse var id = new Identity("test", ",X2QNUAzSBcJ_e$AV;E\\"); var id2 = Identity.Parse(id.ToString(communicator.ToStringMode), uriFormat: false); var id3 = Identity.Parse(id.ToString()); // new URI style TestHelper.Assert(id == id2); TestHelper.Assert(id == id3); id = new Identity("test", ",X2QNUAz\\SB\\/cJ_e$AV;E\\\\"); id2 = Identity.Parse(id.ToString(communicator.ToStringMode), uriFormat: false); id3 = Identity.Parse(id.ToString()); TestHelper.Assert(id == id2); TestHelper.Assert(id == id3); id = new Identity("/test", "cat/"); string idStr = id.ToString(communicator.ToStringMode); TestHelper.Assert(idStr == "cat\\//\\/test"); id2 = Identity.Parse(idStr, uriFormat: false); id3 = Identity.Parse(id.ToString()); TestHelper.Assert(id == id2); TestHelper.Assert(id == id3); // Input string in ice1 format with various pitfalls idStr = "\\342\\x82\\254\\60\\x9\\60\\"; id = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id.Name == "€0\t0\\" && id.Category.Length == 0); try { // Illegal character < 32 _ = Identity.Parse("xx\01FooBar", uriFormat: false); TestHelper.Assert(false); } catch (FormatException) { } try { // Illegal surrogate _ = Identity.Parse("xx\\ud911", uriFormat: false); TestHelper.Assert(false); } catch (FormatException) { } // Testing bytes 127(\x7F, \177) and € // € is encoded as 0x20AC (UTF-16) and 0xE2 0x82 0xAC (UTF-8) id = new Identity("test", "\x7f€"); idStr = id.ToString(); TestHelper.Assert(idStr == "%7F%E2%82%AC/test"); id2 = Identity.Parse(idStr); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.Unicode); TestHelper.Assert(idStr == "\\u007f€/test"); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.ASCII); TestHelper.Assert(idStr == "\\u007f\\u20ac/test"); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.Compat); TestHelper.Assert(idStr == "\\177\\342\\202\\254/test"); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id == id2); // More unicode character id = new Identity("banana \x0E-\ud83c\udf4c\u20ac\u00a2\u0024", "greek \ud800\udd6a"); idStr = id.ToString(); TestHelper.Assert(idStr == "greek%20%F0%90%85%AA/banana%20%0E-%F0%9F%8D%8C%E2%82%AC%C2%A2%24"); id2 = Identity.Parse(idStr); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.Unicode); TestHelper.Assert(idStr == "greek \ud800\udd6a/banana \\u000e-\ud83c\udf4c\u20ac\u00a2$"); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.ASCII); TestHelper.Assert(idStr == "greek \\U0001016a/banana \\u000e-\\U0001f34c\\u20ac\\u00a2$"); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(id == id2); idStr = id.ToString(ToStringMode.Compat); id2 = Identity.Parse(idStr, uriFormat: false); TestHelper.Assert(idStr == "greek \\360\\220\\205\\252/banana \\016-\\360\\237\\215\\214\\342\\202\\254\\302\\242$"); TestHelper.Assert(id == id2); output.WriteLine("ok"); output.Write("testing proxyToString... "); output.Flush(); b1 = IObjectPrx.Parse(rf, communicator); if (b1.GetConnection() is Connection connection) // not coloc-optimized target { IObjectPrx b2 = connection.CreateProxy(Identity.Parse("fixed"), IObjectPrx.Factory); if (connection.Endpoint.Protocol == Protocol.Ice1) { TestHelper.Assert(b2.ToString() == "fixed -t -e 1.1"); } else { TestHelper.Assert(b2.ToString() == "ice:fixed"); } } output.WriteLine("ok"); output.Write("testing propertyToProxy... "); output.Flush(); string propertyPrefix = "Foo.Proxy"; communicator.SetProperty(propertyPrefix, helper.GetTestProxy("test", 0)); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert( b1.Identity.Name == "test" && b1.Identity.Category.Length == 0 && b1.AdapterId.Length == 0 && b1.Facet.Length == 0); string property; property = propertyPrefix + ".Locator"; TestHelper.Assert(b1.Locator == null); communicator.SetProperty(property, "ice+tcp://host:10000/locator"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.Locator != null && b1.Locator.Identity.Name == "locator"); communicator.SetProperty(property, ""); property = propertyPrefix + ".LocatorCacheTimeout"; TestHelper.Assert(b1.LocatorCacheTimeout == Timeout.InfiniteTimeSpan); communicator.SetProperty(property, "1s"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.LocatorCacheTimeout == TimeSpan.FromSeconds(1)); communicator.SetProperty(property, ""); // Now retest with an indirect proxy. communicator.SetProperty(propertyPrefix, "test"); property = propertyPrefix + ".Locator"; communicator.SetProperty(property, "ice+tcp://host:10000/locator"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.Locator != null && b1.Locator.Identity.Name == "locator"); communicator.SetProperty(property, ""); property = propertyPrefix + ".LocatorCacheTimeout"; TestHelper.Assert(b1.LocatorCacheTimeout == Timeout.InfiniteTimeSpan); communicator.SetProperty(property, "1s"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.LocatorCacheTimeout == TimeSpan.FromSeconds(1)); communicator.SetProperty(property, ""); // This cannot be tested so easily because the property is cached // on communicator initialization. // //communicator.SetProperty("Default.LocatorCacheTimeout", "60"); //b1 = communicator.propertyToProxy(propertyPrefix); //TestHelper.Assert(b1.LocatorCacheTimeout == 60); //communicator.SetProperty("Default.LocatorCacheTimeout", ""); communicator.SetProperty(propertyPrefix, helper.GetTestProxy("test", 0)); property = propertyPrefix + ".Router"; TestHelper.Assert(b1.Router == null); communicator.SetProperty(property, "ice+tcp://host:10000/router"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.Router != null && b1.Router.Identity.Name == "router"); communicator.RemoveProperty(property); property = propertyPrefix + ".PreferNonSecure"; TestHelper.Assert(b1.PreferNonSecure); communicator.SetProperty(property, "0"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(!b1.PreferNonSecure); communicator.RemoveProperty(property); property = propertyPrefix + ".ConnectionCached"; TestHelper.Assert(b1.IsConnectionCached); communicator.SetProperty(property, "0"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(!b1.IsConnectionCached); communicator.RemoveProperty(property); property = propertyPrefix + ".InvocationTimeout"; TestHelper.Assert(b1.InvocationTimeout == -1); communicator.SetProperty(property, "1000"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.InvocationTimeout == 1000); communicator.RemoveProperty(property); property = propertyPrefix + ".EndpointSelection"; TestHelper.Assert(b1.EndpointSelection == EndpointSelectionType.Random); communicator.SetProperty(property, "Random"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.EndpointSelection == EndpointSelectionType.Random); communicator.SetProperty(property, "Ordered"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.EndpointSelection == EndpointSelectionType.Ordered); communicator.RemoveProperty(property); property = propertyPrefix + ".Context.c1"; TestHelper.Assert(!b1.Context.ContainsKey("c1")); communicator.SetProperty(property, "TEST"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.Context["c1"].Equals("TEST")); property = propertyPrefix + ".Context.c2"; TestHelper.Assert(!b1.Context.ContainsKey("c2")); communicator.SetProperty(property, "TEST"); b1 = communicator.GetPropertyAsProxy(propertyPrefix, IObjectPrx.Factory) !; TestHelper.Assert(b1.Context["c2"].Equals("TEST")); communicator.SetProperty(propertyPrefix + ".Context.c1", ""); communicator.SetProperty(propertyPrefix + ".Context.c2", ""); output.WriteLine("ok"); output.Write("testing IObjectPrx.ToProperty... "); output.Flush(); IRouterPrx router = IRouterPrx.Parse("ice:router?encoding=1.1", communicator).Clone( cacheConnection: true, preferNonSecure: true, endpointSelection: EndpointSelectionType.Random, locatorCacheTimeout: TimeSpan.FromSeconds(200), invocationTimeout: 1500); ILocatorPrx?locator = ILocatorPrx.Parse("ice:locator", communicator).Clone( cacheConnection: false, preferNonSecure: true, endpointSelection: EndpointSelectionType.Random, locatorCacheTimeout: TimeSpan.FromSeconds(300), invocationTimeout: 1500, router: router); b1 = IObjectPrx.Parse("ice:test", communicator).Clone( cacheConnection: true, preferNonSecure: false, endpointSelection: EndpointSelectionType.Ordered, locatorCacheTimeout: TimeSpan.FromSeconds(100), invocationTimeout: 1234, locator: locator); Dictionary <string, string> proxyProps = b1.ToProperty("Test"); TestHelper.Assert(proxyProps.Count == 18); TestHelper.Assert(proxyProps["Test"] == "ice:test"); TestHelper.Assert(proxyProps["Test.ConnectionCached"] == "1"); TestHelper.Assert(proxyProps["Test.PreferNonSecure"] == "0"); TestHelper.Assert(proxyProps["Test.EndpointSelection"] == "Ordered"); TestHelper.Assert(proxyProps["Test.LocatorCacheTimeout"] == "100s"); TestHelper.Assert(proxyProps["Test.InvocationTimeout"] == "1234"); TestHelper.Assert(proxyProps["Test.Locator"] == "ice:locator"); // strange test with an indirect locator! TestHelper.Assert(proxyProps["Test.Locator.ConnectionCached"] == "0"); TestHelper.Assert(proxyProps["Test.Locator.PreferNonSecure"] == "1"); TestHelper.Assert(proxyProps["Test.Locator.EndpointSelection"] == "Random"); TestHelper.Assert(proxyProps["Test.Locator.LocatorCacheTimeout"] == "5m"); TestHelper.Assert(proxyProps["Test.Locator.InvocationTimeout"] == "1500"); TestHelper.Assert(proxyProps["Test.Locator.Router"] == "ice:router?encoding=1.1"); // also very strange TestHelper.Assert(proxyProps["Test.Locator.Router.ConnectionCached"] == "1"); TestHelper.Assert(proxyProps["Test.Locator.Router.PreferNonSecure"] == "1"); TestHelper.Assert(proxyProps["Test.Locator.Router.EndpointSelection"] == "Random"); TestHelper.Assert(proxyProps["Test.Locator.Router.LocatorCacheTimeout"] == "200s"); TestHelper.Assert(proxyProps["Test.Locator.Router.InvocationTimeout"] == "1500"); output.WriteLine("ok"); output.Write("testing IObjectPrx.Communicator... "); output.Flush(); TestHelper.Assert(baseProxy.Communicator == communicator); output.WriteLine("ok"); output.Write("testing proxy Clone... "); TestHelper.Assert(baseProxy.Clone(facet: "facet", IObjectPrx.Factory).Facet == "facet"); TestHelper.Assert(baseProxy.Clone(adapterId: "id").AdapterId.Equals("id")); TestHelper.Assert(!baseProxy.Clone(invocationMode: InvocationMode.Twoway).IsOneway); TestHelper.Assert(baseProxy.Clone(invocationMode: InvocationMode.Oneway).IsOneway); TestHelper.Assert(baseProxy.Clone(invocationMode: InvocationMode.Datagram).IsOneway); TestHelper.Assert(baseProxy.Clone(invocationMode: InvocationMode.BatchOneway).InvocationMode == InvocationMode.BatchOneway); TestHelper.Assert(baseProxy.Clone(invocationMode: InvocationMode.Datagram).InvocationMode == InvocationMode.Datagram); TestHelper.Assert(baseProxy.Clone(invocationMode: InvocationMode.BatchDatagram).InvocationMode == InvocationMode.BatchDatagram); TestHelper.Assert(baseProxy.Clone(preferNonSecure: true).PreferNonSecure); TestHelper.Assert(!baseProxy.Clone(preferNonSecure: false).PreferNonSecure); try { baseProxy.Clone(invocationTimeout: 0); TestHelper.Assert(false); } catch (ArgumentException) { } try { baseProxy.Clone(invocationTimeout: -1); } catch (ArgumentException) { TestHelper.Assert(false); } try { baseProxy.Clone(invocationTimeout: -2); TestHelper.Assert(false); } catch (ArgumentException) { } try { baseProxy.Clone(locatorCacheTimeout: TimeSpan.Zero); } catch (ArgumentException) { TestHelper.Assert(false); } try { baseProxy.Clone(locatorCacheTimeout: Timeout.InfiniteTimeSpan); } catch (ArgumentException) { TestHelper.Assert(false); } try { baseProxy.Clone(locatorCacheTimeout: TimeSpan.FromSeconds(-2)); TestHelper.Assert(false); } catch (ArgumentException) { } output.WriteLine("ok"); output.Write("testing proxy comparison... "); output.Flush(); TestHelper.Assert(IObjectPrx.Parse("ice:foo", communicator).Equals(IObjectPrx.Parse("ice:foo", communicator))); TestHelper.Assert(!IObjectPrx.Parse("ice:foo", communicator).Equals(IObjectPrx.Parse("ice:foo2", communicator))); var compObj = IObjectPrx.Parse("ice:foo", communicator); TestHelper.Assert(compObj.Clone(facet: "facet", IObjectPrx.Factory).Equals( compObj.Clone(facet: "facet", IObjectPrx.Factory))); TestHelper.Assert(!compObj.Clone(facet: "facet", IObjectPrx.Factory).Equals( compObj.Clone(facet: "facet1", IObjectPrx.Factory))); TestHelper.Assert(compObj.Clone(invocationMode: InvocationMode.Oneway).Equals( compObj.Clone(invocationMode: InvocationMode.Oneway))); TestHelper.Assert(!compObj.Clone(invocationMode: InvocationMode.Oneway).Equals( compObj.Clone(invocationMode: InvocationMode.Twoway))); TestHelper.Assert(compObj.Clone(cacheConnection: true).Equals(compObj.Clone(cacheConnection: true))); TestHelper.Assert(!compObj.Clone(cacheConnection: false).Equals(compObj.Clone(cacheConnection: true))); TestHelper.Assert(compObj.Clone(endpointSelection: EndpointSelectionType.Random).Equals( compObj.Clone(endpointSelection: EndpointSelectionType.Random))); TestHelper.Assert(!compObj.Clone(endpointSelection: EndpointSelectionType.Random).Equals( compObj.Clone(endpointSelection: EndpointSelectionType.Ordered))); TestHelper.Assert(compObj.Clone(connectionId: "id2").Equals(compObj.Clone(connectionId: "id2"))); TestHelper.Assert(!compObj.Clone(connectionId: "id1").Equals(compObj.Clone(connectionId: "id2"))); TestHelper.Assert(compObj.Clone(connectionId: "id1").ConnectionId.Equals("id1")); TestHelper.Assert(compObj.Clone(connectionId: "id2").ConnectionId.Equals("id2")); var loc1 = ILocatorPrx.Parse("ice+tcp://host:10000/loc1", communicator); var loc2 = ILocatorPrx.Parse("ice+tcp://host:10000/loc2", communicator); TestHelper.Assert(compObj.Clone(clearLocator: true).Equals(compObj.Clone(clearLocator: true))); TestHelper.Assert(compObj.Clone(locator: loc1).Equals(compObj.Clone(locator: loc1))); TestHelper.Assert(!compObj.Clone(locator: loc1).Equals(compObj.Clone(clearLocator: true))); TestHelper.Assert(!compObj.Clone(clearLocator: true).Equals(compObj.Clone(locator: loc2))); TestHelper.Assert(!compObj.Clone(locator: loc1).Equals(compObj.Clone(locator: loc2))); var rtr1 = IRouterPrx.Parse("ice+tcp://host:10000/rtr1", communicator); var rtr2 = IRouterPrx.Parse("ice+tcp://host:10000/rtr2", communicator); TestHelper.Assert(compObj.Clone(clearRouter: true).Equals(compObj.Clone(clearRouter: true))); TestHelper.Assert(compObj.Clone(router: rtr1).Equals(compObj.Clone(router: rtr1))); TestHelper.Assert(!compObj.Clone(router: rtr1).Equals(compObj.Clone(clearRouter: true))); TestHelper.Assert(!compObj.Clone(clearRouter: true).Equals(compObj.Clone(router: rtr2))); TestHelper.Assert(!compObj.Clone(router: rtr1).Equals(compObj.Clone(router: rtr2))); var ctx1 = new Dictionary <string, string> { ["ctx1"] = "v1" }; var ctx2 = new Dictionary <string, string> { ["ctx2"] = "v2" }; TestHelper.Assert(compObj.Clone(context: new Dictionary <string, string>()).Equals( compObj.Clone(context: new Dictionary <string, string>()))); TestHelper.Assert(compObj.Clone(context: ctx1).Equals(compObj.Clone(context: ctx1))); TestHelper.Assert(!compObj.Clone(context: ctx1).Equals( compObj.Clone(context: new Dictionary <string, string>()))); TestHelper.Assert(!compObj.Clone(context: new Dictionary <string, string>()).Equals( compObj.Clone(context: ctx2))); TestHelper.Assert(!compObj.Clone(context: ctx1).Equals(compObj.Clone(context: ctx2))); TestHelper.Assert(compObj.Clone(preferNonSecure: true).Equals(compObj.Clone(preferNonSecure: true))); TestHelper.Assert(!compObj.Clone(preferNonSecure: true).Equals(compObj.Clone(preferNonSecure: false))); var compObj1 = IObjectPrx.Parse("ice+tcp://127.0.0.1:10000/foo", communicator); var compObj2 = IObjectPrx.Parse("ice+tcp://127.0.0.1:10001/foo", communicator); TestHelper.Assert(!compObj1.Equals(compObj2)); compObj1 = IObjectPrx.Parse("ice:MyAdapter1//foo", communicator); compObj2 = IObjectPrx.Parse("ice:MyAdapter2//foo", communicator); TestHelper.Assert(!compObj1.Equals(compObj2)); TestHelper.Assert(compObj1.Clone(locatorCacheTimeout: TimeSpan.FromSeconds(20)) .Equals(compObj1.Clone(locatorCacheTimeout: TimeSpan.FromSeconds(20)))); TestHelper.Assert(!compObj1.Clone(locatorCacheTimeout: TimeSpan.FromSeconds(10)) .Equals(compObj1.Clone(locatorCacheTimeout: TimeSpan.FromSeconds(20)))); TestHelper.Assert(compObj1.Clone(invocationTimeout: 20).Equals(compObj1.Clone(invocationTimeout: 20))); TestHelper.Assert(!compObj1.Clone(invocationTimeout: 10).Equals(compObj1.Clone(invocationTimeout: 20))); compObj1 = IObjectPrx.Parse("ice+tcp://127.0.0.1:10000/foo", communicator); compObj2 = IObjectPrx.Parse("ice:MyAdapter1//foo", communicator); TestHelper.Assert(!compObj1.Equals(compObj2)); IReadOnlyList <Endpoint> endpts1 = IObjectPrx.Parse("ice+tcp://127.0.0.1:10000/foo", communicator).Endpoints; IReadOnlyList <Endpoint> endpts2 = IObjectPrx.Parse("ice+tcp://127.0.0.1:10001/foo", communicator).Endpoints; TestHelper.Assert(!endpts1[0].Equals(endpts2[0])); TestHelper.Assert(endpts1[0].Equals( IObjectPrx.Parse("ice+tcp://127.0.0.1:10000/foo", communicator).Endpoints[0])); if (baseProxy.GetConnection() is Connection baseConnection) { Connection baseConnection2 = baseProxy.Clone(connectionId: "base2").GetConnection() !; compObj1 = compObj1.Clone(fixedConnection: baseConnection); compObj2 = compObj2.Clone(fixedConnection: baseConnection2); TestHelper.Assert(!compObj1.Equals(compObj2)); } output.WriteLine("ok"); output.Write("testing checked cast... "); output.Flush(); var cl = IMyClassPrx.CheckedCast(baseProxy); TestHelper.Assert(cl != null); var derived = IMyDerivedClassPrx.CheckedCast(cl); TestHelper.Assert(derived != null); TestHelper.Assert(cl.Equals(baseProxy)); TestHelper.Assert(derived.Equals(baseProxy)); TestHelper.Assert(cl.Equals(derived)); try { IMyDerivedClassPrx.CheckedCast(cl.Clone(facet: "facet", IObjectPrx.Factory)); TestHelper.Assert(false); } catch (ObjectNotExistException) { } output.WriteLine("ok"); output.Write("testing checked cast with context... "); output.Flush(); Dictionary <string, string> c = cl.GetContext(); TestHelper.Assert(c == null || c.Count == 0); c = new Dictionary <string, string> { ["one"] = "hello", ["two"] = "world" }; cl = IMyClassPrx.CheckedCast(baseProxy, c); Dictionary <string, string> c2 = cl !.GetContext(); TestHelper.Assert(c.DictionaryEquals(c2)); output.WriteLine("ok"); output.Write("testing ice_fixed... "); output.Flush(); { if (cl.GetConnection() is Connection connection2) { TestHelper.Assert(!cl.IsFixed); IMyClassPrx prx = cl.Clone(fixedConnection: connection2); TestHelper.Assert(prx.IsFixed); prx.IcePing(); TestHelper.Assert(cl.Clone("facet", IObjectPrx.Factory, fixedConnection: connection2).Facet == "facet"); TestHelper.Assert(cl.Clone(invocationMode: InvocationMode.Oneway, fixedConnection: connection2).IsOneway); var ctx = new Dictionary <string, string> { ["one"] = "hello", ["two"] = "world" }; TestHelper.Assert(cl.Clone(fixedConnection: connection2).Context.Count == 0); TestHelper.Assert(cl.Clone(context: ctx, fixedConnection: connection2).Context.Count == 2); TestHelper.Assert(cl.Clone(fixedConnection: connection2).InvocationTimeout == -1); TestHelper.Assert(cl.Clone(invocationTimeout: 10, fixedConnection: connection2).InvocationTimeout == 10); TestHelper.Assert(cl.Clone(fixedConnection: connection2).GetConnection() == connection2); TestHelper.Assert(cl.Clone(fixedConnection: connection2).Clone(fixedConnection: connection2).GetConnection() == connection2); Connection?fixedConnection = cl.Clone(connectionId: "ice_fixed").GetConnection(); TestHelper.Assert(cl.Clone(fixedConnection: connection2).Clone(fixedConnection: fixedConnection).GetConnection() == fixedConnection); try { cl.Clone(invocationMode: InvocationMode.Datagram, fixedConnection: connection2); TestHelper.Assert(false); } catch (ArgumentException) { } } } output.WriteLine("ok"); output.Write("testing encoding versioning... "); string ref13 = helper.GetTestProxy("test", 0); IMyClassPrx cl13 = IMyClassPrx.Parse(ref13, communicator).Clone(encoding: new Encoding(1, 3)); try { cl13.IcePing(); TestHelper.Assert(false); } catch (NotSupportedException) { // expected } output.WriteLine("ok"); if (communicator.DefaultProtocol == Protocol.Ice2) { output.Write("testing protocol versioning... "); output.Flush(); string ref3 = helper.GetTestProxy("test", 0); ref3 += "?protocol=3"; string transport = helper.GetTestTransport(); ref3 = ref3.Replace($"ice+{transport}", "ice+universal"); ref3 += $"&transport={transport}"; var cl3 = IMyClassPrx.Parse(ref3, communicator); try { cl3.IcePing(); TestHelper.Assert(false); } catch (NotSupportedException) { // expected } output.WriteLine("ok"); } output.Write("testing ice2 universal endpoints... "); output.Flush(); var p1 = IObjectPrx.Parse("ice+universal://127.0.0.1:4062/test?transport=tcp", communicator); TestHelper.Assert(p1.ToString() == "ice+tcp://127.0.0.1/test"); // uses default port p1 = IObjectPrx.Parse( "ice+universal://127.0.0.1:4062/test?transport=tcp&alt-endpoint=host2:10000?transport=tcp", communicator); TestHelper.Assert(p1.ToString() == "ice+tcp://127.0.0.1/test?alt-endpoint=host2:10000"); p1 = IObjectPrx.Parse( "ice+universal://127.0.0.1:4062/test?transport=tcp&alt-endpoint=host2:10000?transport=99$option=a", communicator); TestHelper.Assert(p1.ToString() == "ice+tcp://127.0.0.1/test?alt-endpoint=ice+universal://host2:10000?transport=99$option=a"); output.WriteLine("ok"); output.Write("testing ice1 opaque endpoints... "); output.Flush(); // Legal TCP endpoint expressed as opaque endpoint p1 = IObjectPrx.Parse("test:opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==", communicator); TestHelper.Assert(p1.ToString() == "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000"); // Two legal TCP endpoints expressed as opaque endpoints p1 = IObjectPrx.Parse(@"test:opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==: opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA==", communicator); TestHelper.Assert(p1.ToString() == "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000"); // Test that an SSL endpoint and an unknown-transport endpoint get written back out as an opaque // endpoint. p1 = IObjectPrx.Parse( "test:opaque -e 1.1 -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -e 1.1 -t 99 -v abch", communicator); TestHelper.Assert(p1.ToString() == "test -t -e 1.1:ssl -h 127.0.0.1 -p 10001 -t -1:opaque -t 99 -e 1.1 -v abch"); output.WriteLine("ok"); output.Write("testing communicator shutdown/destroy... "); output.Flush(); { var com = new Communicator(); com.ShutdownAsync(); com.WaitForShutdownAsync(); com.Dispose(); com.ShutdownAsync(); com.WaitForShutdownAsync(); com.Dispose(); } output.WriteLine("ok"); return(cl); }