aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@google.com>2015-06-08 17:51:36 -0700
committerGravatar Jan Tattermusch <jtattermusch@google.com>2015-06-09 15:59:38 -0700
commit2ddb5a6cb54c88ccf36af81f79160150a40df0be (patch)
treeeb90f7d449b3ff6a3c0bdd94f88a51746181d22d /src/csharp
parenta561ea66aeb460c6f33cfabff396d5ef2b748791 (diff)
revamp of c# channel options
Diffstat (limited to 'src/csharp')
-rw-r--r--src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs105
-rw-r--r--src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj6
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/ChannelArgsSafeHandleTest.cs75
-rw-r--r--src/csharp/Grpc.Core/Channel.cs40
-rw-r--r--src/csharp/Grpc.Core/ChannelArgs.cs115
-rw-r--r--src/csharp/Grpc.Core/ChannelOptions.cs179
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj6
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs9
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs8
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c10
11 files changed, 413 insertions, 148 deletions
diff --git a/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs
new file mode 100644
index 0000000000..ee846eae96
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs
@@ -0,0 +1,105 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Internal.Tests
+{
+ public class ChannelOptionsTest
+ {
+ [Test]
+ public void IntOption()
+ {
+ var option = new ChannelOption("somename", 1);
+
+ Assert.AreEqual(ChannelOption.OptionType.Integer, option.Type);
+ Assert.AreEqual("somename", option.Name);
+ Assert.AreEqual(1, option.IntValue);
+ Assert.Throws(typeof(InvalidOperationException), () => {var s = option.StringValue; });
+ }
+
+ [Test]
+ public void StringOption()
+ {
+ var option = new ChannelOption("somename", "ABCDEF");
+
+ Assert.AreEqual(ChannelOption.OptionType.String, option.Type);
+ Assert.AreEqual("somename", option.Name);
+ Assert.AreEqual("ABCDEF", option.StringValue);
+ Assert.Throws(typeof(InvalidOperationException), () => {var s = option.IntValue; });
+ }
+
+ [Test]
+ public void ConstructorPreconditions()
+ {
+ Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption(null, "abc"); });
+ Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption(null, 1); });
+ Assert.Throws(typeof(NullReferenceException), () => { new ChannelOption("abc", null); });
+ }
+
+ [Test]
+ public void CreateChannelArgsNull()
+ {
+ var channelArgs = ChannelOptions.CreateChannelArgs(null);
+ Assert.IsTrue(channelArgs.IsInvalid);
+ }
+
+ [Test]
+ public void CreateChannelArgsEmpty()
+ {
+ var options = new List<ChannelOption>();
+ var channelArgs = ChannelOptions.CreateChannelArgs(options);
+ channelArgs.Dispose();
+ }
+
+ [Test]
+ public void CreateChannelArgs()
+ {
+ var options = new List<ChannelOption>
+ {
+ new ChannelOption("ABC", "XYZ"),
+ new ChannelOption("somename", "IJKLM"),
+ new ChannelOption("intoption", 12345),
+ new ChannelOption("GHIJK", 12345),
+ };
+
+ var channelArgs = ChannelOptions.CreateChannelArgs(options);
+ channelArgs.Dispose();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 029653967b..92e28b7d74 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -3,8 +3,6 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{86EC5CB4-4EA2-40A2-8057-86542A0353BB}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Grpc.Core.Tests</RootNamespace>
@@ -48,6 +46,8 @@
<Compile Include="Internal\MetadataArraySafeHandleTest.cs" />
<Compile Include="Internal\CompletionQueueSafeHandleTest.cs" />
<Compile Include="Internal\CompletionQueueEventTest.cs" />
+ <Compile Include="Internal\ChannelArgsSafeHandleTest.cs" />
+ <Compile Include="ChannelOptionsTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -63,4 +63,4 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/csharp/Grpc.Core.Tests/Internal/ChannelArgsSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/ChannelArgsSafeHandleTest.cs
new file mode 100644
index 0000000000..af0aaa5f01
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/Internal/ChannelArgsSafeHandleTest.cs
@@ -0,0 +1,75 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Internal.Tests
+{
+ public class ChannelArgsSafeHandleTest
+ {
+ [Test]
+ public void CreateEmptyAndDestroy()
+ {
+ var channelArgs = ChannelArgsSafeHandle.Create(0);
+ channelArgs.Dispose();
+ }
+
+ [Test]
+ public void CreateNonEmptyAndDestroy()
+ {
+ var channelArgs = ChannelArgsSafeHandle.Create(5);
+ channelArgs.Dispose();
+ }
+
+ [Test]
+ public void CreateNullAndDestroy()
+ {
+ var channelArgs = ChannelArgsSafeHandle.CreateNull();
+ channelArgs.Dispose();
+ }
+
+ [Test]
+ public void CreateFillAndDestroy()
+ {
+ var channelArgs = ChannelArgsSafeHandle.Create(3);
+ channelArgs.SetInteger(0, "somekey", 12345);
+ channelArgs.SetString(1, "somekey", "abcdefghijkl");
+ channelArgs.SetString(2, "somekey", "XYZ");
+ channelArgs.Dispose();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 44b610f65b..d6bfbb7bc4 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -29,6 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -50,10 +51,10 @@ namespace Grpc.Core
/// </summary>
/// <param name="host">The DNS name of IP address of the host.</param>
/// <param name="credentials">Optional credentials to create a secure channel.</param>
- /// <param name="channelArgs">Optional channel arguments.</param>
- public Channel(string host, Credentials credentials = null, ChannelArgs channelArgs = null)
+ /// <param name="options">Channel options.</param>
+ public Channel(string host, Credentials credentials = null, IEnumerable<ChannelOption> options = null)
{
- using (ChannelArgsSafeHandle nativeChannelArgs = CreateNativeChannelArgs(channelArgs))
+ using (ChannelArgsSafeHandle nativeChannelArgs = ChannelOptions.CreateChannelArgs(options))
{
if (credentials != null)
{
@@ -67,7 +68,7 @@ namespace Grpc.Core
this.handle = ChannelSafeHandle.Create(host, nativeChannelArgs);
}
}
- this.target = GetOverridenTarget(host, channelArgs);
+ this.target = GetOverridenTarget(host, options);
}
/// <summary>
@@ -76,9 +77,9 @@ namespace Grpc.Core
/// <param name="host">DNS name or IP address</param>
/// <param name="port">the port</param>
/// <param name="credentials">Optional credentials to create a secure channel.</param>
- /// <param name="channelArgs">Optional channel arguments.</param>
- public Channel(string host, int port, Credentials credentials = null, ChannelArgs channelArgs = null) :
- this(string.Format("{0}:{1}", host, port), credentials, channelArgs)
+ /// <param name="options">Channel options.</param>
+ public Channel(string host, int port, Credentials credentials = null, IEnumerable<ChannelOption> options = null) :
+ this(string.Format("{0}:{1}", host, port), credentials, options)
{
}
@@ -112,22 +113,25 @@ namespace Grpc.Core
}
}
- private static string GetOverridenTarget(string target, ChannelArgs args)
+ /// <summary>
+ /// Look for SslTargetNameOverride option and return its value instead of originalTarget
+ /// if found.
+ /// </summary>
+ private static string GetOverridenTarget(string originalTarget, IEnumerable<ChannelOption> options)
{
- if (args != null && !string.IsNullOrEmpty(args.GetSslTargetNameOverride()))
+ if (options == null)
{
- return args.GetSslTargetNameOverride();
+ return originalTarget;
}
- return target;
- }
-
- private static ChannelArgsSafeHandle CreateNativeChannelArgs(ChannelArgs args)
- {
- if (args == null)
+ foreach (var option in options)
{
- return ChannelArgsSafeHandle.CreateNull();
+ if (option.Type == ChannelOption.OptionType.String
+ && option.Name == ChannelOptions.SslTargetNameOverride)
+ {
+ return option.StringValue;
+ }
}
- return args.ToNativeChannelArgs();
+ return originalTarget;
}
}
}
diff --git a/src/csharp/Grpc.Core/ChannelArgs.cs b/src/csharp/Grpc.Core/ChannelArgs.cs
deleted file mode 100644
index 74ab310e44..0000000000
--- a/src/csharp/Grpc.Core/ChannelArgs.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-#region Copyright notice and license
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Grpc.Core.Internal;
-
-namespace Grpc.Core
-{
- /// <summary>
- /// gRPC channel options.
- /// </summary>
- public class ChannelArgs
- {
- public const string SslTargetNameOverrideKey = "grpc.ssl_target_name_override";
-
- readonly ImmutableDictionary<string, string> stringArgs;
-
- private ChannelArgs(ImmutableDictionary<string, string> stringArgs)
- {
- this.stringArgs = stringArgs;
- }
-
- public string GetSslTargetNameOverride()
- {
- string result;
- if (stringArgs.TryGetValue(SslTargetNameOverrideKey, out result))
- {
- return result;
- }
- return null;
- }
-
- public static Builder CreateBuilder()
- {
- return new Builder();
- }
-
- public class Builder
- {
- readonly Dictionary<string, string> stringArgs = new Dictionary<string, string>();
-
- // TODO: AddInteger not supported yet.
- public Builder AddString(string key, string value)
- {
- stringArgs.Add(key, value);
- return this;
- }
-
- public ChannelArgs Build()
- {
- return new ChannelArgs(stringArgs.ToImmutableDictionary());
- }
- }
-
- /// <summary>
- /// Creates native object for the channel arguments.
- /// </summary>
- /// <returns>The native channel arguments.</returns>
- internal ChannelArgsSafeHandle ToNativeChannelArgs()
- {
- ChannelArgsSafeHandle nativeArgs = null;
- try
- {
- nativeArgs = ChannelArgsSafeHandle.Create(stringArgs.Count);
- int i = 0;
- foreach (var entry in stringArgs)
- {
- nativeArgs.SetString(i, entry.Key, entry.Value);
- i++;
- }
- return nativeArgs;
- }
- catch (Exception)
- {
- if (nativeArgs != null)
- {
- nativeArgs.Dispose();
- }
- throw;
- }
- }
- }
-}
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
new file mode 100644
index 0000000000..4d37b39682
--- /dev/null
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -0,0 +1,179 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Channel option specified when creating a channel.
+ /// Corresponds to grpc_channel_args from grpc/grpc.h.
+ /// </summary>
+ public sealed class ChannelOption
+ {
+ public enum OptionType
+ {
+ Integer,
+ String
+ }
+
+ private readonly OptionType type;
+ private readonly string name;
+ private readonly int intValue;
+ private readonly string stringValue;
+
+ /// <summary>
+ /// Creates a channel option with a string value.
+ /// </summary>
+ /// <param name="name">Name.</param>
+ /// <param name="stringValue">String value.</param>
+ public ChannelOption(string name, string stringValue)
+ {
+ this.type = OptionType.String;
+ this.name = Preconditions.CheckNotNull(name);
+ this.stringValue = Preconditions.CheckNotNull(stringValue);
+ }
+
+ /// <summary>
+ /// Creates a channel option with an integer value.
+ /// </summary>
+ /// <param name="name">Name.</param>
+ /// <param name="stringValue">String value.</param>
+ public ChannelOption(string name, int intValue)
+ {
+ this.type = OptionType.Integer;
+ this.name = Preconditions.CheckNotNull(name);
+ this.intValue = intValue;
+ }
+
+ public OptionType Type
+ {
+ get
+ {
+ return type;
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ return name;
+ }
+ }
+
+ public int IntValue
+ {
+ get
+ {
+ Preconditions.CheckState(type == OptionType.Integer);
+ return intValue;
+ }
+ }
+
+ public string StringValue
+ {
+ get
+ {
+ Preconditions.CheckState(type == OptionType.String);
+ return stringValue;
+ }
+ }
+ }
+
+ public static class ChannelOptions
+ {
+ // Override SSL target check. Only to be used for testing.
+ public const string SslTargetNameOverride = "grpc.ssl_target_name_override";
+
+ // Enable census for tracing and stats collection
+ public const string Census = "grpc.census";
+
+ // Maximum number of concurrent incoming streams to allow on a http2 connection
+ public const string MaxConcurrentStreams = "grpc.max_concurrent_streams";
+
+ // Maximum message length that the channel can receive
+ public const string MaxMessageLength = "grpc.max_message_length";
+
+ // Initial sequence number for http2 transports
+ public const string Http2InitialSequenceNumber = "grpc.http2.initial_sequence_number";
+
+ /// <summary>
+ /// Creates native object for a collection of channel options.
+ /// </summary>
+ /// <returns>The native channel arguments.</returns>
+ internal static ChannelArgsSafeHandle CreateChannelArgs(IEnumerable<ChannelOption> options)
+ {
+ if (options == null)
+ {
+ return ChannelArgsSafeHandle.CreateNull();
+ }
+ var optionList = new List<ChannelOption>(options); // It's better to do defensive copy
+ ChannelArgsSafeHandle nativeArgs = null;
+ try
+ {
+ nativeArgs = ChannelArgsSafeHandle.Create(optionList.Count);
+ for (int i = 0; i < optionList.Count; i++)
+ {
+ var option = optionList[i];
+ if (option.Type == ChannelOption.OptionType.Integer)
+ {
+ nativeArgs.SetInteger(i, option.Name, option.IntValue);
+ }
+ else if (option.Type == ChannelOption.OptionType.String)
+ {
+ nativeArgs.SetString(i, option.Name, option.StringValue);
+ }
+ else
+ {
+ throw new InvalidOperationException("Unknown option type");
+ }
+
+ }
+ return nativeArgs;
+ }
+ catch (Exception)
+ {
+ if (nativeArgs != null)
+ {
+ nativeArgs.Dispose();
+ }
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 5c7b9a8bb6..a36a6a5acc 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -5,8 +5,6 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Grpc.Core</RootNamespace>
@@ -78,7 +76,6 @@
<Compile Include="Internal\CredentialsSafeHandle.cs" />
<Compile Include="Credentials.cs" />
<Compile Include="Internal\ChannelArgsSafeHandle.cs" />
- <Compile Include="ChannelArgs.cs" />
<Compile Include="Internal\AsyncCompletion.cs" />
<Compile Include="Internal\AsyncCallBase.cs" />
<Compile Include="Internal\AsyncCallServer.cs" />
@@ -103,6 +100,7 @@
<Compile Include="Internal\CompletionQueueEvent.cs" />
<Compile Include="Internal\CompletionRegistry.cs" />
<Compile Include="Internal\BatchContextSafeHandle.cs" />
+ <Compile Include="ChannelOptions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -132,4 +130,4 @@
</Target>
<Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" />
<Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
index c69f1a0d02..c12aec5a3a 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
@@ -45,6 +45,9 @@ namespace Grpc.Core.Internal
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
+
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_args_destroy(IntPtr args);
@@ -67,6 +70,11 @@ namespace Grpc.Core.Internal
grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value);
}
+ public void SetInteger(int index, string key, int value)
+ {
+ grpcsharp_channel_args_set_integer(this, new UIntPtr((uint)index), key, value);
+ }
+
protected override bool ReleaseHandle()
{
grpcsharp_channel_args_destroy(handle);
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 66171fae57..faee5a8fa5 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -110,14 +110,15 @@ namespace Grpc.IntegrationTesting
credentials = TestCredentials.CreateTestClientCredentials(options.useTestCa);
}
- ChannelArgs channelArgs = null;
+ List<ChannelOption> channelOptions = null;
if (!string.IsNullOrEmpty(options.serverHostOverride))
{
- channelArgs = ChannelArgs.CreateBuilder()
- .AddString(ChannelArgs.SslTargetNameOverrideKey, options.serverHostOverride).Build();
+ channelOptions = new List<ChannelOption> {
+ new ChannelOption(ChannelOptions.SslTargetNameOverride, options.serverHostOverride)
+ };
}
- using (Channel channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelArgs))
+ using (Channel channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelOptions))
{
var stubConfig = StubConfiguration.Default;
if (options.testCase == "service_account_creds" || options.testCase == "compute_engine_creds")
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index f756dfbc40..33628ce4c7 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -62,10 +62,10 @@ namespace Grpc.IntegrationTesting
int port = server.AddListeningPort(host, Server.PickUnusedPort, TestCredentials.CreateTestServerCredentials());
server.Start();
- var channelArgs = ChannelArgs.CreateBuilder()
- .AddString(ChannelArgs.SslTargetNameOverrideKey, TestCredentials.DefaultHostOverride).Build();
-
- channel = new Channel(host, port, TestCredentials.CreateTestClientCredentials(true), channelArgs);
+ var options = new List<ChannelOption> {
+ new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride)
+ };
+ channel = new Channel(host, port, TestCredentials.CreateTestClientCredentials(true), options);
client = TestService.NewStub(channel);
}
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 57be445331..59b8993ad3 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -355,6 +355,16 @@ grpcsharp_channel_args_set_string(grpc_channel_args *args, size_t index,
}
GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_channel_args_set_integer(grpc_channel_args *args, size_t index,
+ const char *key, int value) {
+ GPR_ASSERT(args);
+ GPR_ASSERT(index < args->num_args);
+ args->args[index].type = GRPC_ARG_INTEGER;
+ args->args[index].key = gpr_strdup(key);
+ args->args[index].value.integer = value;
+}
+
+GPR_EXPORT void GPR_CALLTYPE
grpcsharp_channel_args_destroy(grpc_channel_args *args) {
size_t i;
if (args) {