コード例 #1
0
ファイル: PluginI.cs プロジェクト: manics/ice
        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;
            }
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        // 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);
            }
        }
コード例 #4
0
ファイル: Plugin.cs プロジェクト: yuweiApp/ice
 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;
         }
     }
 }
コード例 #5
0
        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;
                }
            }
        }
コード例 #6
0
ファイル: Proxy.cs プロジェクト: shawvi/ice
        /// <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));
        }
コード例 #7
0
ファイル: Proxy.cs プロジェクト: shawvi/ice
 /// <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)));
 }
コード例 #8
0
ファイル: Plugin.cs プロジェクト: bernardnormier/ice
        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);
        }
コード例 #9
0
ファイル: Proxy.cs プロジェクト: yssource/ice
        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));
        }
コード例 #10
0
ファイル: Proxy.cs プロジェクト: mreinart/ice
        /// <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));
        }
コード例 #11
0
        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);
        }
コード例 #12
0
ファイル: Proxy.cs プロジェクト: mreinart/ice
 /// <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));
コード例 #13
0
ファイル: Proxy.cs プロジェクト: jk990803/ice
 /// <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)));
 }
コード例 #14
0
        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);
            }
        }
コード例 #15
0
ファイル: Proxy.cs プロジェクト: keno1213/ice
        /// <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));
        }
コード例 #16
0
        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;
            }
        }
コード例 #17
0
ファイル: Plugin.cs プロジェクト: principleWindows/ice
        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();
        }
コード例 #18
0
        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;
                        }
                    }
                }
            }
        }
コード例 #19
0
        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;
                        }
                    }
                }
            }
        }
コード例 #20
0
ファイル: Plugin.cs プロジェクト: keno1213/ice
        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();
        }
コード例 #21
0
ファイル: Plugin.cs プロジェクト: bernardnormier/ice
        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());
                }
            }
        }
コード例 #22
0
ファイル: Plugin.cs プロジェクト: bernardnormier/ice
 public void FoundLocator(ILocatorPrx?locator, Current current) => _locator.FoundLocator(locator);
コード例 #23
0
        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();
                }
            }
        }
コード例 #24
0
        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();
        }
コード例 #25
0
ファイル: AllTests.cs プロジェクト: bernardnormier/ice
        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);
        }