You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by aa...@apache.org on 2023/03/16 07:35:19 UTC

[rocketmq-clients] branch master updated (5fa06815 -> e554ddb9)

This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git


    from 5fa06815 Set exception for producer ahead of throwing it
     new bbc8fc98 Make it compatible with .NET standard 2.1
     new e4b88580 Add 3.1.x into dotnet-version of CI pipeline
     new 8efac866 Add more docs
     new 2752a445 Update TargetFrameworks to 'net5.0;netcoreapp3.1'
     new e554ddb9 Add more comments

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/csharp_build.yml                 |  1 +
 csharp/README-CN.md                                | 62 ++++++++++++++++
 csharp/README.md                                   | 24 +++++--
 csharp/examples/ProducerBenchmark.cs               | 10 ++-
 csharp/examples/ProducerDelayMessageExample.cs     |  4 +-
 csharp/examples/ProducerFifoMessageExample.cs      |  4 +-
 csharp/examples/ProducerNormalMessageExample.cs    |  4 +-
 .../examples/ProducerTransactionMessageExample.cs  |  4 +-
 csharp/examples/SimpleConsumerExample.cs           |  4 +-
 csharp/examples/examples.csproj                    |  2 +-
 csharp/rocketmq-client-csharp/Client.cs            | 10 ++-
 .../ConfigFileCredentialsProvider.cs               | 83 ----------------------
 csharp/rocketmq-client-csharp/Consumer.cs          |  2 +-
 csharp/rocketmq-client-csharp/Endpoints.cs         |  2 +-
 csharp/rocketmq-client-csharp/Message.cs           |  6 +-
 .../rocketmq-client-csharp/MessageIdGenerator.cs   |  2 +-
 csharp/rocketmq-client-csharp/MessageView.cs       |  6 +-
 csharp/rocketmq-client-csharp/MetadataConstants.cs |  2 +-
 csharp/rocketmq-client-csharp/MetricConstant.cs    |  2 +-
 csharp/rocketmq-client-csharp/MqLogManager.cs      | 10 +--
 csharp/rocketmq-client-csharp/Producer.cs          |  7 +-
 .../PublishingLoadBalancer.cs                      |  2 +-
 csharp/rocketmq-client-csharp/RpcClient.cs         | 21 +++---
 csharp/rocketmq-client-csharp/Session.cs           |  2 +-
 csharp/rocketmq-client-csharp/SimpleConsumer.cs    |  2 +-
 .../SubscriptionLoadBalancer.cs                    |  2 +-
 csharp/rocketmq-client-csharp/UserAgent.cs         |  2 +-
 csharp/rocketmq-client-csharp/Utilities.cs         | 37 +++++++++-
 .../rocketmq-client-csharp.csproj                  | 32 ++++-----
 csharp/tests/ConfigFileCredentialsProviderTest.cs  | 59 ---------------
 csharp/tests/PublishingMessageTest.cs              |  2 +-
 .../tests/{EndpointsTest.cs => UtilitiesTest.cs}   | 26 ++++---
 csharp/tests/tests.csproj                          |  2 +-
 33 files changed, 213 insertions(+), 227 deletions(-)
 create mode 100644 csharp/README-CN.md
 delete mode 100644 csharp/rocketmq-client-csharp/ConfigFileCredentialsProvider.cs
 delete mode 100644 csharp/tests/ConfigFileCredentialsProviderTest.cs
 copy csharp/tests/{EndpointsTest.cs => UtilitiesTest.cs} (54%)


[rocketmq-clients] 04/05: Update TargetFrameworks to 'net5.0;netcoreapp3.1'

Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git

commit 2752a445063623ae96f1f70ecc72013ceb458b35
Author: Aaron Ai <ya...@gmail.com>
AuthorDate: Thu Mar 16 15:25:25 2023 +0800

    Update TargetFrameworks to 'net5.0;netcoreapp3.1'
---
 csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj | 4 ++--
 csharp/tests/tests.csproj                                   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
index 83b0d293..f7036d4b 100644
--- a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
+++ b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
@@ -1,12 +1,12 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <PackageId>RocketMQ.Client</PackageId>
-        <PackageVersion>0.0.14-SNAPSHOT</PackageVersion>
+        <PackageVersion>0.0.15-SNAPSHOT</PackageVersion>
         <Version>$(PackageVersion)</Version>
 
         <Authors>RocketMQ Authors</Authors>
         <Company>Apache Software Foundation</Company>
-        <TargetFrameworks>net5.0;netstandard21</TargetFrameworks>
+        <TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
         <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
         <RootNamespace>Org.Apache.Rocketmq</RootNamespace>
         <PackageReadmeFile>README.md</PackageReadmeFile>
diff --git a/csharp/tests/tests.csproj b/csharp/tests/tests.csproj
index 5268d418..ab8aad59 100644
--- a/csharp/tests/tests.csproj
+++ b/csharp/tests/tests.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
+    <TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
 
     <IsPackable>false</IsPackable>
   </PropertyGroup>


[rocketmq-clients] 01/05: Make it compatible with .NET standard 2.1

Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git

commit bbc8fc987f0488bf29c00dae5cd5553081183154
Author: Aaron Ai <ya...@gmail.com>
AuthorDate: Wed Mar 15 22:35:42 2023 +0800

    Make it compatible with .NET standard 2.1
---
 csharp/examples/ProducerBenchmark.cs               |  8 ++-
 csharp/examples/ProducerDelayMessageExample.cs     |  2 +-
 csharp/examples/ProducerFifoMessageExample.cs      |  2 +-
 csharp/examples/ProducerNormalMessageExample.cs    |  2 +-
 .../examples/ProducerTransactionMessageExample.cs  |  2 +-
 csharp/examples/SimpleConsumerExample.cs           |  2 +-
 csharp/examples/examples.csproj                    |  2 +-
 csharp/rocketmq-client-csharp/Client.cs            | 10 ++-
 .../ConfigFileCredentialsProvider.cs               | 83 ----------------------
 csharp/rocketmq-client-csharp/Consumer.cs          |  2 +-
 csharp/rocketmq-client-csharp/Endpoints.cs         |  2 +-
 csharp/rocketmq-client-csharp/Message.cs           |  6 +-
 .../rocketmq-client-csharp/MessageIdGenerator.cs   |  2 +-
 csharp/rocketmq-client-csharp/MessageView.cs       |  6 +-
 csharp/rocketmq-client-csharp/MetadataConstants.cs |  2 +-
 csharp/rocketmq-client-csharp/MetricConstant.cs    |  2 +-
 csharp/rocketmq-client-csharp/MqLogManager.cs      | 10 +--
 csharp/rocketmq-client-csharp/Producer.cs          |  7 +-
 .../PublishingLoadBalancer.cs                      |  2 +-
 csharp/rocketmq-client-csharp/RpcClient.cs         | 21 +++---
 csharp/rocketmq-client-csharp/Session.cs           |  2 +-
 csharp/rocketmq-client-csharp/SimpleConsumer.cs    |  2 +-
 .../SubscriptionLoadBalancer.cs                    |  2 +-
 csharp/rocketmq-client-csharp/UserAgent.cs         |  2 +-
 csharp/rocketmq-client-csharp/Utilities.cs         | 37 +++++++++-
 .../rocketmq-client-csharp.csproj                  | 32 ++++-----
 csharp/tests/ConfigFileCredentialsProviderTest.cs  | 59 ---------------
 csharp/tests/UtilitiesTest.cs                      | 50 +++++++++++++
 28 files changed, 152 insertions(+), 209 deletions(-)

diff --git a/csharp/examples/ProducerBenchmark.cs b/csharp/examples/ProducerBenchmark.cs
index 7e2679aa..f7de1c89 100644
--- a/csharp/examples/ProducerBenchmark.cs
+++ b/csharp/examples/ProducerBenchmark.cs
@@ -29,11 +29,13 @@ namespace examples
     {
         private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger();
 
-        private static readonly SemaphoreSlim Semaphore = new(0);
+        private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(0);
         private const int TpsLimit = 300;
         private static long _successCounter;
         private static long _failureCounter;
-        private static readonly BlockingCollection<Task<ISendReceipt>> Tasks = new();
+
+        private static readonly BlockingCollection<Task<ISendReceipt>> Tasks =
+            new BlockingCollection<Task<ISendReceipt>>();
 
         private static void DoStats()
         {
@@ -88,7 +90,7 @@ namespace examples
 
             const string topic = "yourNormalTopic";
             // In most case, you don't need to create too many producers, single pattern is recommended.
-            await using var producer = await new Producer.Builder()
+            var producer = await new Producer.Builder()
                 // Set the topic name(s), which is optional but recommended.
                 // It makes producer could prefetch the topic route before message publishing.
                 .SetTopics(topic)
diff --git a/csharp/examples/ProducerDelayMessageExample.cs b/csharp/examples/ProducerDelayMessageExample.cs
index 84808872..5d905408 100644
--- a/csharp/examples/ProducerDelayMessageExample.cs
+++ b/csharp/examples/ProducerDelayMessageExample.cs
@@ -43,7 +43,7 @@ namespace examples
             const string topic = "yourDelayTopic";
             // In most case, you don't need to create too many producers, single pattern is recommended.
             // Producer here will be closed automatically.
-            await using var producer = await new Producer.Builder()
+            var producer = await new Producer.Builder()
                 // Set the topic name(s), which is optional but recommended.
                 // It makes producer could prefetch the topic route before message publishing.
                 .SetTopics(topic)
diff --git a/csharp/examples/ProducerFifoMessageExample.cs b/csharp/examples/ProducerFifoMessageExample.cs
index 6a96fa0a..0ce94ee3 100644
--- a/csharp/examples/ProducerFifoMessageExample.cs
+++ b/csharp/examples/ProducerFifoMessageExample.cs
@@ -43,7 +43,7 @@ namespace examples
             const string topic = "yourFifoTopic";
             // In most case, you don't need to create too many producers, single pattern is recommended.
             // Producer here will be closed automatically.
-            await using var producer = await new Producer.Builder()
+            var producer = await new Producer.Builder()
                 // Set the topic name(s), which is optional but recommended.
                 // It makes producer could prefetch the topic route before message publishing.
                 .SetTopics(topic)
diff --git a/csharp/examples/ProducerNormalMessageExample.cs b/csharp/examples/ProducerNormalMessageExample.cs
index b9b85b73..2598c739 100644
--- a/csharp/examples/ProducerNormalMessageExample.cs
+++ b/csharp/examples/ProducerNormalMessageExample.cs
@@ -42,7 +42,7 @@ namespace examples
             const string topic = "yourNormalTopic";
             // In most case, you don't need to create too many producers, single pattern is recommended.
             // Producer here will be closed automatically.
-            await using var producer = await new Producer.Builder()
+            var producer = await new Producer.Builder()
                 // Set the topic name(s), which is optional but recommended.
                 // It makes producer could prefetch the topic route before message publishing.
                 .SetTopics(topic)
diff --git a/csharp/examples/ProducerTransactionMessageExample.cs b/csharp/examples/ProducerTransactionMessageExample.cs
index 1b5b7aa4..dff74268 100644
--- a/csharp/examples/ProducerTransactionMessageExample.cs
+++ b/csharp/examples/ProducerTransactionMessageExample.cs
@@ -51,7 +51,7 @@ namespace examples
             const string topic = "yourTransactionTopic";
             // In most case, you don't need to create too many producers, single pattern is recommended.
             // Producer here will be closed automatically.
-            await using var producer = await new Producer.Builder()
+            var producer = await new Producer.Builder()
                 // Set the topic name(s), which is optional but recommended.
                 // It makes producer could prefetch the topic route before message publishing.
                 .SetTopics(topic)
diff --git a/csharp/examples/SimpleConsumerExample.cs b/csharp/examples/SimpleConsumerExample.cs
index fd0d9d7a..11dbedb0 100644
--- a/csharp/examples/SimpleConsumerExample.cs
+++ b/csharp/examples/SimpleConsumerExample.cs
@@ -46,7 +46,7 @@ namespace examples
             var subscription = new Dictionary<string, FilterExpression>
                 { { topic, new FilterExpression("*") } };
             // In most case, you don't need to create too many consumers, single pattern is recommended.
-            await using var simpleConsumer = await new SimpleConsumer.Builder()
+            var simpleConsumer = await new SimpleConsumer.Builder()
                 .SetClientConfig(clientConfig)
                 .SetConsumerGroup(consumerGroup)
                 .SetAwaitDuration(TimeSpan.FromSeconds(15))
diff --git a/csharp/examples/examples.csproj b/csharp/examples/examples.csproj
index ebdf0af4..37f6a477 100644
--- a/csharp/examples/examples.csproj
+++ b/csharp/examples/examples.csproj
@@ -5,6 +5,6 @@
 
     <PropertyGroup>
         <OutputType>Exe</OutputType>
-        <TargetFramework>net5.0</TargetFramework>
+        <TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
     </PropertyGroup>
 </Project>
diff --git a/csharp/rocketmq-client-csharp/Client.cs b/csharp/rocketmq-client-csharp/Client.cs
index ec0ea6a7..d619280b 100644
--- a/csharp/rocketmq-client-csharp/Client.cs
+++ b/csharp/rocketmq-client-csharp/Client.cs
@@ -205,7 +205,7 @@ namespace Org.Apache.Rocketmq
             try
             {
                 Logger.Info($"Start to update topic route cache for a new round, clientId={ClientId}");
-                Dictionary<string, Task<TopicRouteData>> responses = new();
+                Dictionary<string, Task<TopicRouteData>> responses = new Dictionary<string, Task<TopicRouteData>>();
 
                 foreach (var topic in GetTopics())
                 {
@@ -255,9 +255,7 @@ namespace Org.Apache.Rocketmq
             ThreadPool.GetAvailableThreads(out var availableWorker, out var availableIo);
             Logger.Info(
                 $"ClientId={ClientId}, ClientVersion={MetadataConstants.Instance.ClientVersion}, " +
-                $".NET Version={Environment.Version}, ThreadCount={ThreadPool.ThreadCount}, " +
-                $"CompletedWorkItemCount={ThreadPool.CompletedWorkItemCount}, " +
-                $"PendingWorkItemCount={ThreadPool.PendingWorkItemCount}, AvailableWorkerThreads={availableWorker}, " +
+                $".NET Version={Environment.Version}, AvailableWorkerThreads={availableWorker}, " +
                 $"AvailableCompletionPortThreads={availableIo}");
         }
 
@@ -345,8 +343,8 @@ namespace Org.Apache.Rocketmq
             {
                 var endpoints = GetTotalRouteEndpoints();
                 var request = WrapHeartbeatRequest();
-                Dictionary<Endpoints, Task<RpcInvocation<Proto.HeartbeatRequest, Proto.HeartbeatResponse>>>
-                    invocations = new();
+                var invocations =
+                    new Dictionary<Endpoints, Task<RpcInvocation<Proto.HeartbeatRequest, Proto.HeartbeatResponse>>>();
 
                 // Collect task into a map.
                 foreach (var item in endpoints)
diff --git a/csharp/rocketmq-client-csharp/ConfigFileCredentialsProvider.cs b/csharp/rocketmq-client-csharp/ConfigFileCredentialsProvider.cs
deleted file mode 100644
index 93b9e9ef..00000000
--- a/csharp/rocketmq-client-csharp/ConfigFileCredentialsProvider.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.IO;
-using System;
-using System.Text.Json;
-using System.Collections.Generic;
-using NLog;
-
-namespace Org.Apache.Rocketmq
-{
-    /**
-     * File-based credentials provider that reads JSON configurations from ${HOME}/.rocketmq/config
-     * A sample config content is as follows:
-     * {"AccessKey": "key", "AccessSecret": "secret"}
-     */
-    public class ConfigFileCredentialsProvider
-    {
-        private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger();
-
-        public ConfigFileCredentialsProvider()
-        {
-            var configFilePath = DefaultConfigFilePath();
-
-            if (!File.Exists(configFilePath))
-            {
-                Logger.Warn("Config file[{}] does not exist", configFilePath);
-                return;
-            }
-
-            try
-            {
-                using var reader = new StreamReader(configFilePath);
-                string json = reader.ReadToEnd();
-                var kv = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
-                if (null == kv)
-                {
-                    Logger.Error($"Failed to parse JSON configuration: {json}");
-                    return;
-                }
-
-                _accessKey = kv["AccessKey"];
-                _accessSecret = kv["AccessSecret"];
-                _valid = true;
-            }
-            catch (IOException e)
-            {
-                Logger.Error($"Failed to read cofig file. Cause: {e.Message}");
-            }
-        }
-
-        public SessionCredentials GetCredentials()
-        {
-            return !_valid ? null : new SessionCredentials(_accessKey, _accessSecret);
-        }
-
-        public static string DefaultConfigFilePath()
-        {
-            var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
-            string[] pathSegments = { home, ".rocketmq", "config" };
-            return string.Join(Path.DirectorySeparatorChar, pathSegments);
-        }
-
-        private readonly string _accessKey;
-        private readonly string _accessSecret;
-
-        private readonly bool _valid;
-    }
-}
\ No newline at end of file
diff --git a/csharp/rocketmq-client-csharp/Consumer.cs b/csharp/rocketmq-client-csharp/Consumer.cs
index 998a3766..0bf7a45a 100644
--- a/csharp/rocketmq-client-csharp/Consumer.cs
+++ b/csharp/rocketmq-client-csharp/Consumer.cs
@@ -27,7 +27,7 @@ namespace Org.Apache.Rocketmq
 {
     public abstract class Consumer : Client
     {
-        internal static readonly Regex ConsumerGroupRegex = new("^[%a-zA-Z0-9_-]+$");
+        internal static readonly Regex ConsumerGroupRegex = new Regex("^[%a-zA-Z0-9_-]+$");
         protected readonly string ConsumerGroup;
 
         protected Consumer(ClientConfig clientConfig, string consumerGroup) : base(
diff --git a/csharp/rocketmq-client-csharp/Endpoints.cs b/csharp/rocketmq-client-csharp/Endpoints.cs
index dbf9bdfb..dc015e2b 100644
--- a/csharp/rocketmq-client-csharp/Endpoints.cs
+++ b/csharp/rocketmq-client-csharp/Endpoints.cs
@@ -28,7 +28,7 @@ namespace Org.Apache.Rocketmq
         private const string HttpsPrefix = "https://";
         private const int DefaultPort = 80;
 
-        private static readonly AddressListEqualityComparer AddressListComparer = new();
+        private static readonly AddressListEqualityComparer AddressListComparer = new AddressListEqualityComparer();
         private const string EndpointSeparator = ":";
         public List<Address> Addresses { get; }
         private AddressScheme Scheme { get; }
diff --git a/csharp/rocketmq-client-csharp/Message.cs b/csharp/rocketmq-client-csharp/Message.cs
index b71a4650..bbd2c20e 100644
--- a/csharp/rocketmq-client-csharp/Message.cs
+++ b/csharp/rocketmq-client-csharp/Message.cs
@@ -24,7 +24,7 @@ namespace Org.Apache.Rocketmq
 {
     public class Message
     {
-        internal static readonly Regex TopicRegex = new("^[%a-zA-Z0-9_-]+$");
+        internal static readonly Regex TopicRegex = new Regex("^[%a-zA-Z0-9_-]+$");
 
         private Message(string topic, byte[] body, string tag, List<string> keys,
             Dictionary<string, string> properties, DateTime? deliveryTimestamp, string messageGroup)
@@ -75,8 +75,8 @@ namespace Org.Apache.Rocketmq
             private string _topic;
             private byte[] _body;
             private string _tag;
-            private List<string> _keys = new();
-            private readonly Dictionary<string, string> _properties = new();
+            private List<string> _keys = new List<string>();
+            private readonly Dictionary<string, string> _properties = new Dictionary<string, string>();
             private DateTime? _deliveryTimestamp;
             private string _messageGroup;
 
diff --git a/csharp/rocketmq-client-csharp/MessageIdGenerator.cs b/csharp/rocketmq-client-csharp/MessageIdGenerator.cs
index 60620ef0..b55b0456 100644
--- a/csharp/rocketmq-client-csharp/MessageIdGenerator.cs
+++ b/csharp/rocketmq-client-csharp/MessageIdGenerator.cs
@@ -28,7 +28,7 @@ namespace Org.Apache.Rocketmq
     public class MessageIdGenerator
     {
         public const string Version = "01";
-        private static readonly MessageIdGenerator Instance = new();
+        private static readonly MessageIdGenerator Instance = new MessageIdGenerator();
 
         private readonly string _prefix;
 
diff --git a/csharp/rocketmq-client-csharp/MessageView.cs b/csharp/rocketmq-client-csharp/MessageView.cs
index 461f7781..63906344 100644
--- a/csharp/rocketmq-client-csharp/MessageView.cs
+++ b/csharp/rocketmq-client-csharp/MessageView.cs
@@ -104,7 +104,7 @@ namespace Org.Apache.Rocketmq
                     }
                 case Proto.DigestType.Md5:
                     {
-                        var expectedCheckSum = Convert.ToHexString(MD5.HashData(raw));
+                        var expectedCheckSum = Utilities.ComputeMd5Hash(raw);
                         if (!expectedCheckSum.Equals(checkSum))
                         {
                             corrupted = true;
@@ -114,7 +114,7 @@ namespace Org.Apache.Rocketmq
                     }
                 case Proto.DigestType.Sha1:
                     {
-                        var expectedCheckSum = Convert.ToHexString(SHA1.HashData(raw));
+                        var expectedCheckSum = Utilities.ComputeSha1Hash(raw);
                         if (!expectedCheckSum.Equals(checkSum))
                         {
                             corrupted = true;
@@ -158,7 +158,7 @@ namespace Org.Apache.Rocketmq
             var messageGroup = systemProperties.HasMessageGroup ? systemProperties.MessageGroup : null;
             DateTime? deliveryTime = null == systemProperties.DeliveryTimestamp
                 ? null
-                : TimeZoneInfo.ConvertTimeFromUtc(systemProperties.DeliveryTimestamp.ToDateTime(), TimeZoneInfo.Local);
+                : (DateTime?)TimeZoneInfo.ConvertTimeFromUtc(systemProperties.DeliveryTimestamp.ToDateTime(), TimeZoneInfo.Local);
             var keys = systemProperties.Keys.ToList();
 
             var bornHost = systemProperties.BornHost;
diff --git a/csharp/rocketmq-client-csharp/MetadataConstants.cs b/csharp/rocketmq-client-csharp/MetadataConstants.cs
index 07907758..1deddcd2 100644
--- a/csharp/rocketmq-client-csharp/MetadataConstants.cs
+++ b/csharp/rocketmq-client-csharp/MetadataConstants.cs
@@ -43,7 +43,7 @@ namespace Org.Apache.Rocketmq
         public string ClientVersion { get; }
 
 
-        public static readonly MetadataConstants Instance = new();
+        public static readonly MetadataConstants Instance = new MetadataConstants();
 
         private MetadataConstants()
         {
diff --git a/csharp/rocketmq-client-csharp/MetricConstant.cs b/csharp/rocketmq-client-csharp/MetricConstant.cs
index e19288de..bfc64b40 100644
--- a/csharp/rocketmq-client-csharp/MetricConstant.cs
+++ b/csharp/rocketmq-client-csharp/MetricConstant.cs
@@ -42,7 +42,7 @@ namespace Org.Apache.Rocketmq
         public readonly ExplicitBucketHistogramConfiguration AwaitTimeBucket;
         public readonly ExplicitBucketHistogramConfiguration ProcessTimeBucket;
 
-        public static readonly MetricConstant Instance = new();
+        public static readonly MetricConstant Instance = new MetricConstant();
 
         private MetricConstant()
         {
diff --git a/csharp/rocketmq-client-csharp/MqLogManager.cs b/csharp/rocketmq-client-csharp/MqLogManager.cs
index 1e67bb56..1e68ea43 100644
--- a/csharp/rocketmq-client-csharp/MqLogManager.cs
+++ b/csharp/rocketmq-client-csharp/MqLogManager.cs
@@ -33,19 +33,19 @@ namespace Org.Apache.Rocketmq
     {
         public static LogFactory Instance => LazyInstance.Value;
 
-        private static readonly Lazy<LogFactory> LazyInstance = new(BuildLogFactory);
+        private static readonly Lazy<LogFactory> LazyInstance = new Lazy<LogFactory>(BuildLogFactory);
 
-        private const string FileLogLevelKey = "rocketmq.log.level";
+        private const string FileLogLevelKey = "rocketmq_log_level";
         private const string FileLogLevel = "Info";
 
-        private const string ConsoleAppenderEnabledKey = "mq.consoleAppender.enabled";
+        private const string ConsoleAppenderEnabledKey = "mq_consoleAppender_enabled";
         private const string ConsoleAppenderEnabled = "false";
         private const string ConsoleAppenderLogLevel = "Off";
 
 
-        private const string FileLogRootKey = "rocketmq.log.root";
+        private const string FileLogRootKey = "rocketmq_log_root";
 
-        private const string FileMaxIndexKey = "rocketmq.log.file.maxIndex";
+        private const string FileMaxIndexKey = "rocketmq_log_file_maxIndex";
         private const string FileMaxIndex = "10";
 
         private static LogFactory BuildLogFactory()
diff --git a/csharp/rocketmq-client-csharp/Producer.cs b/csharp/rocketmq-client-csharp/Producer.cs
index a1f70989..78ee4e34 100644
--- a/csharp/rocketmq-client-csharp/Producer.cs
+++ b/csharp/rocketmq-client-csharp/Producer.cs
@@ -259,7 +259,7 @@ namespace Org.Apache.Rocketmq
                         throw;
                     }
 
-                    if (exception is not TooManyRequestsException)
+                    if (!(exception is TooManyRequestsException))
                     {
                         // Retry immediately if the request is not throttled.
                         Logger.Warn(e, $"Failed to send message, topic={message.Topic}, maxAttempts={maxAttempts}, " +
@@ -349,7 +349,10 @@ namespace Org.Apache.Rocketmq
         public class Builder
         {
             private ClientConfig _clientConfig;
-            private readonly ConcurrentDictionary<string, bool> _publishingTopics = new();
+
+            private readonly ConcurrentDictionary<string, bool> _publishingTopics =
+                new ConcurrentDictionary<string, bool>();
+
             private int _maxAttempts = 3;
             private ITransactionChecker _checker;
 
diff --git a/csharp/rocketmq-client-csharp/PublishingLoadBalancer.cs b/csharp/rocketmq-client-csharp/PublishingLoadBalancer.cs
index b0cc0d2b..84285999 100644
--- a/csharp/rocketmq-client-csharp/PublishingLoadBalancer.cs
+++ b/csharp/rocketmq-client-csharp/PublishingLoadBalancer.cs
@@ -24,7 +24,7 @@ namespace Org.Apache.Rocketmq
 {
     public class PublishingLoadBalancer
     {
-        private static readonly Random Random = new();
+        private static readonly Random Random = new Random();
 
         private readonly List<MessageQueue> _messageQueues;
         private int _index;
diff --git a/csharp/rocketmq-client-csharp/RpcClient.cs b/csharp/rocketmq-client-csharp/RpcClient.cs
index abf70563..b8a02430 100644
--- a/csharp/rocketmq-client-csharp/RpcClient.cs
+++ b/csharp/rocketmq-client-csharp/RpcClient.cs
@@ -19,6 +19,7 @@ using System;
 using System.Collections.Generic;
 using System.Net.Http;
 using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading.Tasks;
 using Proto = Apache.Rocketmq.V2;
@@ -55,23 +56,23 @@ namespace Org.Apache.Rocketmq
             }
         }
 
+        private static bool CertValidator(
+            object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+        {
+            // Always return true to disable server certificate validation
+            return true;
+        }
+
         /**
          * See https://docs.microsoft.com/en-us/aspnet/core/grpc/performance?view=aspnetcore-6.0 for performance consideration and
          * why parameters are configured this way.
          */
         internal static HttpMessageHandler CreateHttpHandler()
         {
-            var sslOptions = new SslClientAuthenticationOptions
-            {
-                // Comment out the following line if server certificate validation is required. 
-                // Disable server certificate validation during development phase.
-                RemoteCertificateValidationCallback = (_, _, _, _) => true
-            };
-            var handler = new SocketsHttpHandler
+            // TODO
+            var handler = new HttpClientHandler
             {
-                PooledConnectionIdleTimeout = Timeout.InfiniteTimeSpan,
-                EnableMultipleHttp2Connections = true,
-                SslOptions = sslOptions,
+                ServerCertificateCustomValidationCallback = CertValidator,
             };
             return handler;
         }
diff --git a/csharp/rocketmq-client-csharp/Session.cs b/csharp/rocketmq-client-csharp/Session.cs
index 69a2c197..f41694ec 100644
--- a/csharp/rocketmq-client-csharp/Session.cs
+++ b/csharp/rocketmq-client-csharp/Session.cs
@@ -31,7 +31,7 @@ namespace Org.Apache.Rocketmq
         private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger();
 
         private static readonly TimeSpan SettingsInitializationTimeout = TimeSpan.FromSeconds(3);
-        private readonly ManualResetEventSlim _event = new(false);
+        private readonly ManualResetEventSlim _event = new ManualResetEventSlim(false);
 
         private readonly AsyncDuplexStreamingCall<Proto::TelemetryCommand, Proto::TelemetryCommand>
             _streamingCall;
diff --git a/csharp/rocketmq-client-csharp/SimpleConsumer.cs b/csharp/rocketmq-client-csharp/SimpleConsumer.cs
index 2146e643..da372177 100644
--- a/csharp/rocketmq-client-csharp/SimpleConsumer.cs
+++ b/csharp/rocketmq-client-csharp/SimpleConsumer.cs
@@ -110,7 +110,7 @@ namespace Org.Apache.Rocketmq
                 State = State.Stopping;
                 Logger.Info($"Begin to shutdown the rocketmq simple consumer, clientId={ClientId}");
                 await base.Shutdown();
-                Logger.Info($"The rocketmq simple consumer starts successfully, clientId={ClientId}");
+                Logger.Info($"Shutdown the rocketmq simple consumer successfully, clientId={ClientId}");
                 State = State.Terminated;
             }
             catch (Exception)
diff --git a/csharp/rocketmq-client-csharp/SubscriptionLoadBalancer.cs b/csharp/rocketmq-client-csharp/SubscriptionLoadBalancer.cs
index e2575a4b..a5a88a6b 100644
--- a/csharp/rocketmq-client-csharp/SubscriptionLoadBalancer.cs
+++ b/csharp/rocketmq-client-csharp/SubscriptionLoadBalancer.cs
@@ -24,7 +24,7 @@ namespace Org.Apache.Rocketmq
 {
     internal sealed class SubscriptionLoadBalancer
     {
-        private static readonly Random Random = new();
+        private static readonly Random Random = new Random();
 
         private readonly List<MessageQueue> _messageQueues;
         private int _index;
diff --git a/csharp/rocketmq-client-csharp/UserAgent.cs b/csharp/rocketmq-client-csharp/UserAgent.cs
index b457b608..9b5a1157 100644
--- a/csharp/rocketmq-client-csharp/UserAgent.cs
+++ b/csharp/rocketmq-client-csharp/UserAgent.cs
@@ -26,7 +26,7 @@ namespace Org.Apache.Rocketmq
         private readonly string _platform;
         private readonly string _hostName;
 
-        public static readonly UserAgent Instance = new();
+        public static readonly UserAgent Instance = new UserAgent();
 
         private UserAgent()
         {
diff --git a/csharp/rocketmq-client-csharp/Utilities.cs b/csharp/rocketmq-client-csharp/Utilities.cs
index d032ae1e..5505a277 100644
--- a/csharp/rocketmq-client-csharp/Utilities.cs
+++ b/csharp/rocketmq-client-csharp/Utilities.cs
@@ -19,8 +19,10 @@ using System.Linq;
 using System.Net.NetworkInformation;
 using System.Text;
 using System;
+using System.Diagnostics;
 using System.IO;
 using System.IO.Compression;
+using System.Security.Cryptography;
 using System.Threading;
 
 namespace Org.Apache.Rocketmq
@@ -45,7 +47,7 @@ namespace Org.Apache.Rocketmq
 
         public static int GetProcessId()
         {
-            return Environment.ProcessId;
+            return Process.GetCurrentProcess().Id;
         }
 
         public static string GetHostName()
@@ -56,13 +58,31 @@ namespace Org.Apache.Rocketmq
         public static string GetClientId()
         {
             var hostName = System.Net.Dns.GetHostName();
-            var pid = Environment.ProcessId;
+            var pid = Process.GetCurrentProcess().Id;
             var index = Interlocked.Increment(ref _instanceSequence);
             var nowMillisecond = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds;
             var no = DecimalToBase36(nowMillisecond);
             return $"{hostName}@{pid}@{index}@{no}";
         }
 
+        public static string ComputeMd5Hash(byte[] data)
+        {
+            using (var md5 = MD5.Create())
+            {
+                var hashBytes = md5.ComputeHash(data);
+                return BitConverter.ToString(hashBytes).Replace("-", "");
+            }
+        }
+
+        public static string ComputeSha1Hash(byte[] data)
+        {
+            using (var sha1 = SHA1.Create())
+            {
+                var hashBytes = sha1.ComputeHash(data);
+                return BitConverter.ToString(hashBytes).Replace("-", "");
+            }
+        }
+
 
         private static string DecimalToBase36(long decimalNumber)
         {
@@ -92,6 +112,19 @@ namespace Org.Apache.Rocketmq
             return result.ToString();
         }
 
+        public static byte[] CompressBytesGzip(byte[] src, CompressionLevel level)
+        {
+            using (var ms = new MemoryStream())
+            {
+                using (var gzip = new GZipStream(ms, level))
+                {
+                    gzip.Write(src, 0, src.Length);
+                }
+
+                return ms.ToArray();
+            }
+        }
+
         public static byte[] DecompressBytesGzip(byte[] src)
         {
             var inputStream = new MemoryStream(src);
diff --git a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
index bff3801b..83b0d293 100644
--- a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
+++ b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
@@ -1,12 +1,12 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <PackageId>RocketMQ.Client</PackageId>
-        <PackageVersion>0.0.11-SNAPSHOT</PackageVersion>
+        <PackageVersion>0.0.14-SNAPSHOT</PackageVersion>
         <Version>$(PackageVersion)</Version>
 
         <Authors>RocketMQ Authors</Authors>
         <Company>Apache Software Foundation</Company>
-        <TargetFramework>net5.0</TargetFramework>
+        <TargetFrameworks>net5.0;netstandard21</TargetFrameworks>
         <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
         <RootNamespace>Org.Apache.Rocketmq</RootNamespace>
         <PackageReadmeFile>README.md</PackageReadmeFile>
@@ -18,30 +18,28 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <None Include="..\README.md" Pack="true" PackagePath="\"/>
-        <PackageReference Include="Crc32.NET" Version="1.2.0"/>
-        <PackageReference Include="Google.Protobuf" Version="3.19.4"/>
-        <PackageReference Include="Grpc.Net.Client" Version="2.43.0"/>
+        <None Include="..\README.md" Pack="true" PackagePath="\" />
+        <PackageReference Include="Crc32.NET" Version="1.2.0" />
+        <PackageReference Include="Google.Protobuf" Version="3.19.4" />
+        <PackageReference Include="Grpc.Net.Client" Version="2.43.0" />
         <PackageReference Include="Grpc.Tools" Version="2.43.0">
             <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
             <PrivateAssets>all</PrivateAssets>
         </PackageReference>
-        <PackageReference Include="NLog" Version="4.7.13"/>
-        <PackageReference Include="OpenTelemetry" Version="1.3.1"/>
-        <PackageReference Include="OpenTelemetry.Api" Version="1.3.1"/>
-        <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1"/>
+        <PackageReference Include="NLog" Version="4.7.13" />
+        <PackageReference Include="OpenTelemetry" Version="1.3.1" />
+        <PackageReference Include="OpenTelemetry.Api" Version="1.3.1" />
+        <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1" />
 
-        <Protobuf Include="Protos\apache\rocketmq\v2\definition.proto" ProtoRoot="Protos" GrpcServices="Client"/>
-        <Protobuf Include="Protos\google\rpc\code.proto" ProtoRoot="Protos" GrpcServices="Client"/>
-        <Protobuf Include="Protos\google\rpc\error_details.proto" ProtoRoot="Protos" GrpcServices="Client"/>
-        <Protobuf Include="Protos\google\rpc\status.proto" ProtoRoot="Protos" GrpcServices="Client"/>
+        <Protobuf Include="Protos\apache\rocketmq\v2\definition.proto" ProtoRoot="Protos" GrpcServices="Client" />
+        <Protobuf Include="Protos\google\rpc\code.proto" ProtoRoot="Protos" GrpcServices="Client" />
+        <Protobuf Include="Protos\google\rpc\error_details.proto" ProtoRoot="Protos" GrpcServices="Client" />
+        <Protobuf Include="Protos\google\rpc\status.proto" ProtoRoot="Protos" GrpcServices="Client" />
         <Protobuf Include="Protos\apache\rocketmq\v2\service.proto" ProtoRoot="Protos" GrpcServices="Client">
             <Link>Protos\apache\rocketmq\v2\definition.proto</Link>
             <Link>Protos\google\rpc\status.proto</Link>
             <Link>Protos\google\rpc\error_details.proto</Link>
         </Protobuf>
-        <None Update="logo.png" PackagePath="">
-            <Pack>True</Pack>
-        </None>
+        <None Include="logo.png" Pack="true" PackagePath=""/>
     </ItemGroup>
 </Project>
diff --git a/csharp/tests/ConfigFileCredentialsProviderTest.cs b/csharp/tests/ConfigFileCredentialsProviderTest.cs
deleted file mode 100644
index d65439be..00000000
--- a/csharp/tests/ConfigFileCredentialsProviderTest.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.IO;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Org.Apache.Rocketmq;
-
-namespace tests
-{
-    [TestClass]
-    public class ConfigFileCredentialsProviderTest
-    {
-        [TestInitialize]
-        public void Setup()
-        {
-            var configFilePath = ConfigFileCredentialsProvider.DefaultConfigFilePath();
-            var fileInfo = new FileInfo(configFilePath);
-            var dir = fileInfo.Directory;
-            if (dir != null && !dir.Exists)
-            {
-                dir.Create();
-            }
-
-            var json = "{\"AccessKey\": \"key\", \"AccessSecret\": \"secret\"}";
-            File.WriteAllText(configFilePath, json);
-        }
-
-        [TestMethod]
-        public void TestGetCredentials()
-        {
-            var provider = new ConfigFileCredentialsProvider();
-            var credentials = provider.GetCredentials();
-            Assert.IsNotNull(credentials);
-            Assert.AreEqual(credentials.AccessKey, "key");
-            Assert.AreEqual(credentials.AccessSecret, "secret");
-        }
-
-        [TestCleanup]
-        public void TearDown()
-        {
-            var configFilePath = ConfigFileCredentialsProvider.DefaultConfigFilePath();
-            File.Delete(configFilePath);
-        }
-    }
-}
\ No newline at end of file
diff --git a/csharp/tests/UtilitiesTest.cs b/csharp/tests/UtilitiesTest.cs
new file mode 100644
index 00000000..5c82fcaa
--- /dev/null
+++ b/csharp/tests/UtilitiesTest.cs
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.IO.Compression;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Org.Apache.Rocketmq;
+
+namespace tests
+{
+    [TestClass]
+    public class UtilitiesTest
+    {
+        [TestMethod]
+        public void TestDecompressBytesGzip()
+        {
+            var originalData = new byte[] { 1, 2, 3, 4, 5 };
+            var compressedData = Utilities.CompressBytesGzip(originalData, CompressionLevel.Fastest);
+            CollectionAssert.AreEqual(Utilities.DecompressBytesGzip(compressedData), originalData);
+        }
+
+        [TestMethod]
+        public void TestComputeMd5Hash()
+        {
+            var bytes = Encoding.UTF8.GetBytes("foobar");
+            Assert.AreEqual(Utilities.ComputeMd5Hash(bytes), "3858F62230AC3C915F300C664312C63F");
+        }
+
+        [TestMethod]
+        public void TestComputeSha1Hash()
+        {
+            var bytes = Encoding.UTF8.GetBytes("foobar");
+            Assert.AreEqual(Utilities.ComputeSha1Hash(bytes), "8843D7F92416211DE9EBB963FF4CE28125932878");
+        }
+    }
+}
\ No newline at end of file


[rocketmq-clients] 05/05: Add more comments

Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git

commit e554ddb980290a4d7257a45353dfee85f49e8a2e
Author: Aaron Ai <ya...@gmail.com>
AuthorDate: Thu Mar 16 15:28:51 2023 +0800

    Add more comments
---
 csharp/examples/ProducerBenchmark.cs                 | 2 ++
 csharp/examples/ProducerDelayMessageExample.cs       | 2 ++
 csharp/examples/ProducerFifoMessageExample.cs        | 2 ++
 csharp/examples/ProducerNormalMessageExample.cs      | 2 ++
 csharp/examples/ProducerTransactionMessageExample.cs | 2 ++
 csharp/examples/SimpleConsumerExample.cs             | 2 ++
 6 files changed, 12 insertions(+)

diff --git a/csharp/examples/ProducerBenchmark.cs b/csharp/examples/ProducerBenchmark.cs
index f7de1c89..a379b8d2 100644
--- a/csharp/examples/ProducerBenchmark.cs
+++ b/csharp/examples/ProducerBenchmark.cs
@@ -77,6 +77,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 
diff --git a/csharp/examples/ProducerDelayMessageExample.cs b/csharp/examples/ProducerDelayMessageExample.cs
index 5d905408..761ae7ca 100644
--- a/csharp/examples/ProducerDelayMessageExample.cs
+++ b/csharp/examples/ProducerDelayMessageExample.cs
@@ -29,6 +29,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 
diff --git a/csharp/examples/ProducerFifoMessageExample.cs b/csharp/examples/ProducerFifoMessageExample.cs
index 0ce94ee3..f35ba94c 100644
--- a/csharp/examples/ProducerFifoMessageExample.cs
+++ b/csharp/examples/ProducerFifoMessageExample.cs
@@ -29,6 +29,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 
diff --git a/csharp/examples/ProducerNormalMessageExample.cs b/csharp/examples/ProducerNormalMessageExample.cs
index 2598c739..890a2dc2 100644
--- a/csharp/examples/ProducerNormalMessageExample.cs
+++ b/csharp/examples/ProducerNormalMessageExample.cs
@@ -28,6 +28,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 
diff --git a/csharp/examples/ProducerTransactionMessageExample.cs b/csharp/examples/ProducerTransactionMessageExample.cs
index dff74268..14f3da42 100644
--- a/csharp/examples/ProducerTransactionMessageExample.cs
+++ b/csharp/examples/ProducerTransactionMessageExample.cs
@@ -37,6 +37,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 
diff --git a/csharp/examples/SimpleConsumerExample.cs b/csharp/examples/SimpleConsumerExample.cs
index 11dbedb0..e592e5ee 100644
--- a/csharp/examples/SimpleConsumerExample.cs
+++ b/csharp/examples/SimpleConsumerExample.cs
@@ -29,6 +29,8 @@ namespace examples
 
         internal static async Task QuickStart()
         {
+            // Enable the switch if you use .NET Core 3.1.
+            // AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
             const string accessKey = "yourAccessKey";
             const string secretKey = "yourSecretKey";
 


[rocketmq-clients] 02/05: Add 3.1.x into dotnet-version of CI pipeline

Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git

commit e4b885804dc705fc59fbf39bf4d8e12056f0b78a
Author: Aaron Ai <ya...@gmail.com>
AuthorDate: Thu Mar 16 14:16:11 2023 +0800

    Add 3.1.x into dotnet-version of CI pipeline
---
 .github/workflows/csharp_build.yml    | 1 +
 csharp/tests/PublishingMessageTest.cs | 2 +-
 csharp/tests/tests.csproj             | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/csharp_build.yml b/.github/workflows/csharp_build.yml
index 1a37900d..041f41f8 100644
--- a/.github/workflows/csharp_build.yml
+++ b/.github/workflows/csharp_build.yml
@@ -19,6 +19,7 @@ jobs:
             6.0.x
             7.0.x
             8.0.x
+            3.1.x
       - name: Build artifacts
         working-directory: ./csharp
         run: |
diff --git a/csharp/tests/PublishingMessageTest.cs b/csharp/tests/PublishingMessageTest.cs
index 9f4938c0..c12b9083 100644
--- a/csharp/tests/PublishingMessageTest.cs
+++ b/csharp/tests/PublishingMessageTest.cs
@@ -27,7 +27,7 @@ namespace tests
     public class PublishingMessageTest
     {
         private const string ClientId = "fakeClientId";
-        private static readonly Endpoints Endpoints = new("127.0.0.1:8081");
+        private static readonly Endpoints Endpoints = new Endpoints("127.0.0.1:8081");
 
 
         [TestMethod]
diff --git a/csharp/tests/tests.csproj b/csharp/tests/tests.csproj
index 358b4a12..5268d418 100644
--- a/csharp/tests/tests.csproj
+++ b/csharp/tests/tests.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
 
     <IsPackable>false</IsPackable>
   </PropertyGroup>


[rocketmq-clients] 03/05: Add more docs

Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aaronai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git

commit 8efac8660fc19bbd2a19593aaba54cf84dc19ee5
Author: Aaron Ai <ya...@gmail.com>
AuthorDate: Thu Mar 16 14:48:37 2023 +0800

    Add more docs
---
 csharp/README-CN.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 csharp/README.md    | 24 +++++++++++++++------
 2 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/csharp/README-CN.md b/csharp/README-CN.md
new file mode 100644
index 00000000..6c520489
--- /dev/null
+++ b/csharp/README-CN.md
@@ -0,0 +1,62 @@
+# .NET 客户端
+
+[English](README.md) | 简体中文 | [RocketMQ 官网](https://rocketmq.apache.org/)
+
+## 最小版本支持
+
+支持.NET 5+ 和 .NET Core 3.1。
+
+由于.NET 5 在 2020 年的发布,统一了.NET Framework 和 .NET Core ,并逐渐成为 .NET 开发的主流平台。我们强烈推荐使用.NET
+5 访问 RocketMQ,但是与此同时我们也支持使用 .NET Core 3.1。如果您想使用 .NET Core 3.1 接入 RocketMQ,请在运行之前添加以下代码。
+
+```csharp
+AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true)
+```
+
+关于 .NET 5 的更多介绍,可以参照 [Introducing .NET 5](https://devblogs.microsoft.com/dotnet/introducing-net-5/)。
+
+## 概述
+
+当前客户端基于 [rocketmq-apis](https://github.com/apache/rocketmq-apis)
+中的协议约束和 [gRPC-dotnet](https://github.com/grpc/grpc-dotnet) 进行构建,使用 Protocol Buffers 作为序列化协议。
+
+## 快速开始
+
+使用下面的命令来将客户端添加到你项目的依赖中:
+
+```sh
+dotnet add package RocketMQ.Client
+```
+
+你可以从 [Nuget Gallery](https://www.nuget.org/packages/RocketMQ.Client) 从获取最新的 `RocketMQ.Client`
+版本,我们提供了[代码示例](./examples)来帮助你快速开始。
+
+## 构建
+
+本项目的布局大致遵循[此处的指南](https://docs.microsoft.com/en-us/dotnet/core/tutorials/library-with-visual-studio-code?pivots=dotnet-5-0)
+,解决方案内包含客户端类库,单元测试模块和示例代码模块。假设你处于当前项目的路径下:
+
+```sh
+# 构建项目
+dotnet build
+# 运行单元测试
+dotnet test -l "console;verbosity=detailed"
+```
+
+## 日志系统
+
+我们使用 [NLog](https://nlog-project.org/) 作为日志实现,与 Java 客户端类似,我们允许使用环境来自定义日志相关的配置。
+
+* `rocketmq_log_level`:日志输出级别,默认为INFO。
+* `rocketmq_log_root`
+  :日志输出的根目录。默认路径为 `$HOME/logs/rocketmq`,因此完整路径为 `$HOME/logs/rocketmq/rocketmq-client.log`。
+* `rocketmq_log_file_maxIndex`:要保留的日志文件的最大数量。默认值为 10,单个日志文件的大小限制为 64 MB。暂不支持调整。
+
+除此之外,通过将 `mq_consoleAppender_enabled` 设置为 true,您可以同时将客户端日志输出到控制台进行调试。
+
+## NuGet 包发布步骤
+
+1. 打开命令行,进入 csharp 文件夹。
+2. 执行 `dotnet pack --configuration Release` 命令. 这会创建对应的 NuGet 包到 `bin/Release` 文件夹;
+3. 登录 NuGet Gallery 并登录,点击 `Upload` 按钮并将 nupkg 文件拖入提示框;
+4. 按照 NuGet Gallery 的提示,完成后续步骤。
diff --git a/csharp/README.md b/csharp/README.md
index df85a3fb..06babac7 100644
--- a/csharp/README.md
+++ b/csharp/README.md
@@ -1,11 +1,19 @@
 # The .NET Implementation of Apache RocketMQ Client
 
-Here is the .NET implementation of the client for [Apache RocketMQ](https://rocketmq.apache.org/).
+English | [简体中文](README-CN.md) | [RocketMQ Website](https://rocketmq.apache.org/)
 
 ## Supported .NET Versions
 
+.NET 5+ and .NET Core 3.1 is supported.
+
 Due to the release of .NET 5 in 2020, which unified .NET Framework and .NET Core, and has gradually become the
-mainstream platform for .NET development, the RocketMQ client will support .NET 5 and later versions.
+mainstream platform for .NET development. We strongly recommend using .NET 5 to access RocketMQ, and we also support
+accessing it using .NET Core 3.1. If you want to access it using .NET Core 3.1, please add the following code before
+running it.
+
+```csharp
+AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true)
+```
 
 See more details about .NET 5 from [Introducing .NET 5](https://devblogs.microsoft.com/dotnet/introducing-net-5/).
 
@@ -17,6 +25,8 @@ deserialization during transmission.
 
 ## Quickstart & Build
 
+Use the command below to add client into your dependencies.
+
 ```sh
 dotnet add package RocketMQ.Client
 ```
@@ -42,18 +52,18 @@ dotnet test -l "console;verbosity=detailed"
 We use [NLog](https://nlog-project.org/) as our logging implementation. Similar to the Java binding, we allow the use of
 environment variables to customize the related configuration:
 
-* `rocketmq.log.level`: Log output level, default is INFO.
-* `rocketmq.log.root`: The root directory of the log output. The default path is `$HOME/logs/rocketmq`, so the full path
+* `rocketmq_log_level`: Log output level, default is INFO.
+* `rocketmq_log_root`: The root directory of the log output. The default path is `$HOME/logs/rocketmq`, so the full path
   is `$HOME/logs/rocketmq/rocketmq-client.log`.
-* `rocketmq.log.file.maxIndex`: The maximum number of log files to keep. The default is 10, and the size of a single log
+* `rocketmq_log_file_maxIndex`: The maximum number of log files to keep. The default is 10, and the size of a single log
   file is limited to 64 MB. Adjustment is not supported yet.
 
-Specifically, by setting `mq.consoleAppender.enabled` to true, you can output client logs to the console simultaneously
+Specifically, by setting `mq_consoleAppender_enabled` to true, you can output client logs to the console simultaneously
 if you need debugging.
 
 ## Publishing Steps
 
-1. Open the command prompt, and change the directory to the project folder that you want to package.
+1. Open the command line, and change the directory to the project folder that you want to package.
 2. Run the `dotnet pack --configuration Release` command. This will create a NuGet package in the `bin/Release` folder
    of the project.
 3. To upload the package to NuGet, go to the NuGet website and sign in. Click on the "Upload" button and select the