Skip to content

Commit

Permalink
[ISSUE #776] Add push consumer for normal/fifo message, namespace sup…
Browse files Browse the repository at this point in the history
…port, reentrant message receiving support in C# SDK (#777)

Add push consumer for normal/fifo message, namespace support, reentrant message receiving support in C#

---------

Co-authored-by: tsaitsung-han.tht <tsaitsung-han.tht@alibaba-inc.com>
  • Loading branch information
tsunghanjacktsai and tsaitsung-han.tht authored Sep 19, 2024
1 parent f4c3878 commit 4076e2b
Show file tree
Hide file tree
Showing 68 changed files with 6,110 additions and 78 deletions.
12 changes: 7 additions & 5 deletions csharp/examples/ProducerBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public static class ProducerBenchmark
private static long _successCounter;
private static long _failureCounter;

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

private static readonly BlockingCollection<Task<ISendReceipt>> Tasks =
new BlockingCollection<Task<ISendReceipt>>();

Expand Down Expand Up @@ -79,14 +83,11 @@ internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
const string accessKey = "yourAccessKey";
const string secretKey = "yourSecretKey";

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(accessKey, secretKey);
const string endpoints = "foobar.com:8080";
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(endpoints)
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

Expand All @@ -108,6 +109,7 @@ internal static async Task QuickStart()
.SetTag(tag)
// You could set multiple keys for the single message actually.
.SetKeys("yourMessageKey-7044358f98fc")
.SetMessageGroup("fifo-group")
.Build();

DoStats();
Expand Down
11 changes: 6 additions & 5 deletions csharp/examples/ProducerDelayMessageExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ internal static class ProducerDelayMessageExample
{
private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerDelayMessageExample).FullName);

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
const string accessKey = "yourAccessKey";
const string secretKey = "yourSecretKey";

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(accessKey, secretKey);
const string endpoints = "foobar.com:8080";
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(endpoints)
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

Expand Down
12 changes: 7 additions & 5 deletions csharp/examples/ProducerFifoMessageExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
Expand All @@ -26,18 +27,19 @@ internal static class ProducerFifoMessageExample
{
private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerFifoMessageExample).FullName);

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
const string accessKey = "yourAccessKey";
const string secretKey = "yourSecretKey";

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(accessKey, secretKey);
const string endpoints = "foobar.com:8080";
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(endpoints)
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

Expand Down
12 changes: 7 additions & 5 deletions csharp/examples/ProducerNormalMessageExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
Expand All @@ -26,18 +27,19 @@ internal static class ProducerNormalMessageExample
{
private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerNormalMessageExample).FullName);

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
const string accessKey = "yourAccessKey";
const string secretKey = "yourSecretKey";

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(accessKey, secretKey);
const string endpoints = "foobar.com:8080";
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(endpoints)
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

Expand Down
16 changes: 9 additions & 7 deletions csharp/examples/ProducerTransactionMessageExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
Expand All @@ -26,6 +27,10 @@ internal static class ProducerTransactionMessageExample
{
private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerTransactionMessageExample).FullName);

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

private class TransactionChecker : ITransactionChecker
{
public TransactionResolution Check(MessageView messageView)
Expand All @@ -39,14 +44,11 @@ internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
const string accessKey = "yourAccessKey";
const string secretKey = "yourSecretKey";

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(accessKey, secretKey);
const string endpoints = "foobar.com:8080";
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(endpoints)
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

Expand Down Expand Up @@ -76,9 +78,9 @@ internal static async Task QuickStart()
var sendReceipt = await producer.Send(message, transaction);
Logger.LogInformation("Send transaction message successfully, messageId={}", sendReceipt.MessageId);
// Commit the transaction.
transaction.Commit();
await transaction.Commit();
// Or rollback the transaction.
// transaction.Rollback();
// await transaction.Rollback();

// Close the producer if you don't need it anymore.
await producer.DisposeAsync();
Expand Down
75 changes: 75 additions & 0 deletions csharp/examples/PushConsumerExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Org.Apache.Rocketmq;

namespace examples
{
public class PushConsumerExample
{
private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(PushConsumerExample).FullName);

private static readonly string AccessKey = Environment.GetEnvironmentVariable("ROCKETMQ_ACCESS_KEY");
private static readonly string SecretKey = Environment.GetEnvironmentVariable("ROCKETMQ_SECRET_KEY");
private static readonly string Endpoint = Environment.GetEnvironmentVariable("ROCKETMQ_ENDPOINT");

internal static async Task QuickStart()
{
// Enable the switch if you use .NET Core 3.1 and want to disable TLS/SSL.
// AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

// Credential provider is optional for client configuration.
var credentialsProvider = new StaticSessionCredentialsProvider(AccessKey, SecretKey);
var clientConfig = new ClientConfig.Builder()
.SetEndpoints(Endpoint)
.SetCredentialsProvider(credentialsProvider)
.Build();

// Add your subscriptions.
const string consumerGroup = "yourConsumerGroup";
const string topic = "yourTopic";
var subscription = new Dictionary<string, FilterExpression>
{ { topic, new FilterExpression("*") } };

var pushConsumer = await new PushConsumer.Builder()
.SetClientConfig(clientConfig)
.SetConsumerGroup(consumerGroup)
.SetSubscriptionExpression(subscription)
.SetMessageListener(new CustomMessageListener())
.Build();

Thread.Sleep(Timeout.Infinite);

// Close the push consumer if you don't need it anymore.
// await pushConsumer.DisposeAsync();
}

private class CustomMessageListener : IMessageListener
{
public ConsumeResult Consume(MessageView messageView)
{
// Handle the received message and return consume result.
Logger.LogInformation($"Consume message={messageView}");
return ConsumeResult.SUCCESS;
}
}
}
}
1 change: 1 addition & 0 deletions csharp/examples/QuickStart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static void Main()
// ProducerFifoMessageExample.QuickStart().Wait();
// ProducerDelayMessageExample.QuickStart().Wait();
// ProducerTransactionMessageExample.QuickStart().Wait();
// PushConsumerExample.QuickStart().Wait();
// SimpleConsumerExample.QuickStart().Wait();
// ProducerBenchmark.QuickStart().Wait();
}
Expand Down
51 changes: 51 additions & 0 deletions csharp/rocketmq-client-csharp/Assignment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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;
using System.Collections.Generic;

namespace Org.Apache.Rocketmq
{
public class Assignment
{
public Assignment(MessageQueue messageQueue)
{
MessageQueue = messageQueue ?? throw new ArgumentNullException(nameof(messageQueue));
}

public MessageQueue MessageQueue { get; }

public override bool Equals(object obj)
{
if (this == obj) return true;
if (obj == null || GetType() != obj.GetType()) return false;

var other = (Assignment)obj;
return EqualityComparer<MessageQueue>.Default.Equals(MessageQueue, other.MessageQueue);
}

public override int GetHashCode()
{
return EqualityComparer<MessageQueue>.Default.GetHashCode(MessageQueue);
}

public override string ToString()
{
return $"Assignment{{messageQueue={MessageQueue}}}";
}
}
}
65 changes: 65 additions & 0 deletions csharp/rocketmq-client-csharp/Assignments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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;
using System.Collections.Generic;
using System.Linq;
using Apache.Rocketmq.V2;

namespace Org.Apache.Rocketmq
{
public class Assignments
{
private readonly List<Assignment> _assignmentList;

public Assignments(List<Assignment> assignmentList)
{
_assignmentList = assignmentList;
}

public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}

if (obj == null || GetType() != obj.GetType())
{
return false;
}

var other = (Assignments)obj;
return _assignmentList.SequenceEqual(other._assignmentList);
}

public override int GetHashCode()
{
return HashCode.Combine(_assignmentList);
}

public override string ToString()
{
return $"{nameof(Assignments)} {{ {nameof(_assignmentList)} = {_assignmentList} }}";
}

public List<Assignment> GetAssignmentList()
{
return _assignmentList;
}
}
}
Loading

0 comments on commit 4076e2b

Please sign in to comment.