Coder Social home page Coder Social logo

consuldotnet's Introduction

Consul.NET

G-Research CI NuGet Downloads

Contribute with GitPod Contributors License Twitter Follow

Consul API: 1.7.14 .NET: >= 4.6.1 .NET Core: >= 2.0.0

Consul.NET is a .NET client library for the Consul HTTP API.

For further information, please visit the ๐ŸŒ Consul.NET website.

๐Ÿ“ข Introduction

Consul.NET is a .NET port of the Go Consul API, but reworked to use .NET idioms such as Tasks/CancellationTokens instead of Goroutines/Channels. The majority of the calls directly track the HTTP API, but this API does have additional functionality that is provided in the Go API, like Locks and Semaphores.

๐Ÿ“– Learn more about Consul.NET โ€ข ๐Ÿ“š Documentation

๐Ÿ“ฆ Installation

Consul.NET is available as a NuGet package.

dotnet add package Consul

๐Ÿš€ Getting Started โ€ข ๐Ÿ†• Preview version

๐Ÿ’• Community

If you have any questions, feature requests or bug reports, feel free to open an issue or a pull request.

๐Ÿค Contributing

We welcome contributions to Consul.NET. Please see our Contributing guide for more information.

โšก Contributing โ€ข ๐Ÿ“œ Code of Conduct

๐Ÿ™Œ Thanks goes to these wonderful people:

Contributors

๐Ÿ“„ License

Consul.NET is licensed under the Apache License, Version 2.0.

consuldotnet's People

Contributors

adamreeve avatar akatz0813 avatar alhimik45 avatar anwright-ms avatar c-rindi avatar consul-version-updater[bot] avatar dependabot[bot] avatar electnewt avatar eugenyshchelkanov avatar firerain-fd avatar grounded042 avatar haghajanyan-st avatar highlyunavailable avatar ivankolchanov avatar jgiannuzzi avatar jocelynvelarde avatar latop2604 avatar ljubon avatar marcin-krystianc avatar mfkl avatar mjgoethe avatar naskio avatar normanhh3 avatar pavlovic-ivan avatar pliner avatar sammychinedu2ky avatar sergeyshaykhullin avatar shmutalov avatar vchekan avatar winstxnhdw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

consuldotnet's Issues

Cannot create an associated check for a service with custom check id

Code snippet similar to the following:

var check = new AgentServiceCheck
{
    ID = id,
    Name = checkName,
    HTTP = healthCheckEndpoint
    Interval = healthCheckInterval,
    Timeout = healthCheck.Timeout
};
var service = new AgentServiceRegistration
{
    ID = serviceId,
    Name = name,
    Address = address,
    Port = port,
    Checks = new AgentServiceCheck[] { check }
};
Consul.Agent.ServiceRegister(service).GetAwaiter().GetResult();

raises exception with message: 'BadRequest: Request decode failed: json: unknown field "ID"'

According to consul documentation custom check id can be provided with CheckID attribute which does not exist in class AgentServiceCheck:

public class AgentServiceCheck

Of course workaround using something like this is possible:

public class AgentServiceCheckWhichSolvesIssueUnknownFieldId : AgentServiceCheck
{
    [JsonProperty("CheckID")]
    public string CheckId { get; set; }
}

but I hope there is more correct solution.

CI tests random failures

Our CI tests are currently randomly failing (example).

It seems to be that when the snapshot tests are running at the same time as the lock tests, they can cause some failures. It is because the Consul server is rolled back to a previous snapshot, but in the meantime some sessions and locks get created.

Currently the semaphore test and the lock tests run in parallel to all the other tests because they take quite some time to run. I think that we should fully isolate the snapshot tests from all the other tests so they never run in parallel to them.

Continuous delivery plans

It would be great to have the CI deploy nightly to myget.org or feedz.io.

This would allow users to dogfood nightly build and provide a tighter feedback loop. We can see about this after the ongoing CI improvements are merged.

Add CI for Consul.AspNetCore

Now that we have our initial ASP.NET extensions project, we need to add support in our CI pipeline to build, test, and publish it.

GPRC health check failed

Hello, I have a problem using consumotnet.

client.Agent.ServiceRegister(new AgentServiceRegistration()
            {
                ID = id,
                Name = "win",
                Address = ip,
                Port = port,
                Tags = tags,
                Check = new AgentServiceCheck()
                {
                    Interval = TimeSpan.FromSeconds(12),
                    GRPC = $"{ip}:{port}",
                    GRPCUseTLS = false,
                    Timeout = TimeSpan.FromSeconds(5),//ๆฃ€ๆต‹็ญ‰ๅพ…ๆ—ถ้—ด
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)
                }
            });

The health examination has not passed

Is the GRPC field in AgentServiceCheck filled in correctly?

Consul v1.9.5
nuget Consul 1.6.10.1

CI intermittendly failing tests

CI sometimes fails the test run, I could never repro locally. Started investigating but there are some tricky timing tests as well as time-based implementation logic in the consul code itself.

[xUnit.net 00:00:17.08]       timed out: missing session did not terminate renewal loop
[xUnit.net 00:00:17.08]       Expected: True
[xUnit.net 00:00:17.08]       Actual:   False
[xUnit.net 00:00:17.08]       Stack Trace:
[xUnit.net 00:00:17.10]         SessionTest.cs(170,0): at Consul.Test.SessionTest.<Session_Create_RenewPeriodic_TTLExpire>d__5.MoveNext()
[xUnit.net 00:00:17.10]         --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:17.10]            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
[xUnit.net 00:00:17.10]            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[xUnit.net 00:00:17.10]         --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:17.10]            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
[xUnit.net 00:00:17.10]            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[xUnit.net 00:00:17.10]         --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:17.11]            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
[xUnit.net 00:00:17.11]            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Error: Consul.Test.SessionTest.Session_Create_RenewPeriodic_TTLExpire: timed out: missing session did not terminate renewal loop
  Failed Consul.Test.SessionTest.Session_Create_RenewPeriodic_TTLExpire [11 s]
  Error Message:
   timed out: missing session did not terminate renewal loop

That's one. Seems to rely on code like this, in Session.cs

if (DateTime.Now.Subtract(lastRenewTime) > initialTTL)
{
       throw lastException;
}

Also looked into these

Consul.Test.PolicyTest.Policy_CreateDelete [FAIL]
[xUnit.net 00:00:01.28]       Consul.ConsulRequestException : Unexpected response, status code InternalServerError: The ACL system is currently in legacy mode.
[xUnit.net 00:00:01.28]       Stack Trace:
[xUnit.net 00:00:01.28]         D:\a\consuldotnet\consuldotnet\Consul\Client_PutRequests.cs(352,0): at Consul.PutRequest`2.Execute(CancellationToken ct)
[xUnit.net 00:00:01.28]         D:\a\consuldotnet\consuldotnet\Consul\Policy.cs(135,0): at Consul.Policy.Create(PolicyEntry policy, WriteOptions writeOptions, CancellationToken ct)
[xUnit.net 00:00:01.28]         D:\a\consuldotnet\consuldotnet\Consul.Test\PolicyTest.cs(39,0): at Consul.Test.PolicyTest.Policy_CreateDelete()
[xUnit.net 00:00:01.28]         --- End of stack trace from previous location where exception was thrown ---
Error: Consul.Test.EventTest.Event_FireList: Consul.ConsulRequestException : Unexpected response, status code Forbidden: ACL not found
  Failed Consul.Test.EventTest.Event_FireList [3 ms]
  Error Message:
   Consul.ConsulRequestException : Unexpected response, status code Forbidden: ACL not found
  Stack Trace:
     at Consul.GetRequest`1.Execute(CancellationToken ct) in D:\a\consuldotnet\consuldotnet\Consul\Client_GetRequests.cs:line 89
   at Consul.Test.EventTest.Event_FireList() in D:\a\consuldotnet\consuldotnet\Consul.Test\EventTest.cs:line 32
--- End of stack trace from previous location where exception was thrown ---

Last one should be fixed by mfkl@c796d23

Googling around leads to insight about some potential token generation update needed by new versions of consul, but then I see all the other agents with the same config succeeding and I feel like that's not it and probably also a timing issue.

Event when a KV value changes

Hello,

I'm using consuldotnet for a long time, but when I need to check if a value changes, I need to do it on my own. I think would be nice if this lib could do a check every X minutes for a change in the value and then fire and event with the new value.

I could implement this funcionality and send an PR, if you approve such feature.

Asp.Net Core 3.1 on Windows

Hello,

I did not manage to make Consul.Net library work with .NET Core 3.1 on Windows.

I always face a "Host not found" error while trying to connect to the agent. I tried with a dummy program and with all test unit tests => same result.

It works fine with .NET Core 2.1 and 2.2 in Windows.

I have seen that you have tested .NET Core 3.1 on Linux. Do you confirm the issue on Windows ?

Thanks for your help,
Stephane

Lock Acquire operation null reference exception + cancellation token not respected

Hello!

Recently I've been playing with the distributed lock feature of Consul in an ASP Net Core 3.1 application.
I'm using the latest version of consuldotnet 1.6.1.1
I have a Background service that calls the Task Acquire(CancellationToken ct) continuously in a "block indefinitely" approach (LockTryOnce is left with its default value). I.e. If I am not a leader, then wait until I am. If I was previously a leader, try become leader again in case I lost the leadership (e.g session invalidation).

However, I have the following two issues :

  • If I call Acquire method with an already cancelled token I get a Null Reference Exception from whitin the consul library.
  • If the lock is already held by another instace of my application and my current "slave" instance is in a blocked Acquire call, then when I perform a gracefull shutdown, my BackgroundService cancellaiton token is not respected although I'm passing it to the Acquire method. The Acqurie method still keeps the blocked operation until "LockWaitTime" has passed. Then I again get a Null Reference exception.
    What is even worse is that in order to have my gracefull shutdown complete normally for the entire application I must either increase the ASP Net Core Host ShutDownTimeout or have some custom extension method where I for example do:
    "await Task.WhenAny(AcquireLockTask, TaskThatCompletesUpponCancellationTokenCancelled);"

Edit:
I've just done a quick debug session and I found that:
In the finally block of the Acquire method If I have never started a monitor task (e.g my application never acquried a lock, during its life) it will throw the null reference exception because:
"await _monitorTask.ConfigureAwait(false);" will be "await null.ConfigureAwait(false)".
https://github.com/G-Research/consuldotnet/blob/master/Consul/Lock.cs#L357

However adding an "if" to check if the task _monitorTask is initialised would lead to
"throw new LockNotHeldException("Unable to acquire the lock with Consul");"
https://github.com/G-Research/consuldotnet/blob/master/Consul/Lock.cs#L345
because this was the last thing from the method before the finally block. I'm not sure if this exception would be correct in case of cancellation token being cancelled. Could be, could be not.

For the second issue where the CancellationToken is not respected:
https://github.com/G-Research/consuldotnet/blob/master/Consul/Lock.cs#L278
https://github.com/G-Research/consuldotnet/blob/master/Consul/Lock.cs#L330
This query "await _client.KV.Get(Opts.Key, qOpts).ConfigureAwait(false);" blocks for the amout of time set for LockWaitTime.
Can you please explain why the cancellation token is not passed?

Add possibility to filter service by multiple tags

tag (string: "") - Specifies the tag to filter on. This is specified as part of the URL as a query parameter. Can be used multiple times for additional filtering, returning only the results that include all of the tag values provided.

KV.Release is writing a wrong value

Describe the bug

When using KV.Release to release a previously acquired lock on an item, the Release funcion always write the value bnVsbA== to the item, which corresponds to the base64 encoding of the text null.

This is happening because the Release function is constructing a request whith the form PutRequest<object, bool> and passing null as the body parameter.

Then when the body is serialized, it is serialized as System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), so the result is always bnVsbA==.

To correct this issue the request must be constructed whith the form PutRequest<byte[], bool> and passing the correct value in the body parameter, the same way that it's used in the Acquire request.

Steps To Reproduce

.

Expected behavior

.

Environment

  • OS: Windows 10
  • Consul Version: 1.6.10.4

Logs

No response

Additional context

No response

Improvement: Fix warning for dotnet format

When running dotnet format --check, while it is successful, it displays

Warnings were encountered while loading the workspace. Set the verbosity option to the 'diagnostic' level to log warnings.

Re-running with dotnet format --check -v diag shows

The dotnet CLI version is '5.0.202'.
  Using MSBuild.exe located in 'C:\Program Files\dotnet\sdk\5.0.202\'.
  Formatting code files in workspace 'C:\consuldotnet\Consul.sln'.
  Loading workspace.
  Msbuild failed when processing the file 'C:\consuldotnet\Consul.AspNetCore.Test\Consul.AspNetCore.Test.csproj' with message: Project does not contain 'Compile' target.
  Msbuild failed when processing the file 'C:\consuldotnet\Consul.AspNetCore.Test\Consul.AspNetCore.Test.csproj' with message: Project does not contain 'Compile' target.
  Msbuild failed when processing the file 'C:\consuldotnet\Consul.AspNetCore.Test\Consul.AspNetCore.Test.csproj' with message: Project does not contain 'Compile' target.
  Found project reference without a matching metadata reference: C:\consuldotnet\Consul.AspNetCore\Consul.AspNetCore.csproj
  Complete in 2165ms.
  Determining formattable files.
  Complete in 596ms.
  Running formatters.
  Complete in 329ms.
  Formatted 0 of 280 files.
  Format complete in 3091ms.

Nuget push?

You have a lot of great changes in the code. When do you plan to push your latest to nuget?

Registering a service in a namespace

Curious to know if there is any plan to support namespaces in Consul.NET ?
The namespaces functionality is available only in Consul Enterprise version 1.7.0 and later.

Invalid wait time when trying to acquire a lock that is already held

Describe the bug

When trying to acquire a lock that is already held, we can sometimes get BadRequest: Invalid wait time from the Consul agent.

This has happened at least once when running the Lock_OneShot test. Here is an example stack trace:

2021-07-05T08:40:47.5355523Z ##[error]Consul.Test.LockTest.Lock_OneShot: Assert.Throws() Failure
2021-07-05T08:40:47.5408798Z   Failed Consul.Test.LockTest.Lock_OneShot [1 s]
2021-07-05T08:40:47.5409479Z   Error Message:
2021-07-05T08:40:47.5410692Z    Assert.Throws() Failure
2021-07-05T08:40:47.5411934Z Expected: typeof(Consul.LockMaxAttemptsReachedException)
2021-07-05T08:40:47.5413473Z Actual:   typeof(Consul.ConsulRequestException): Unexpected response, status code BadRequest: Invalid wait time
2021-07-05T08:40:47.5416422Z ---- Consul.ConsulRequestException : Unexpected response, status code BadRequest: Invalid wait time
2021-07-05T08:40:47.5417896Z   Stack Trace:
2021-07-05T08:40:47.5436227Z      at Consul.GetRequest`1.<Execute>d__10.MoveNext()
2021-07-05T08:40:47.5437302Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5439095Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5442304Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5444541Z    at Consul.KV.<Get>d__13.MoveNext()
2021-07-05T08:40:47.5445321Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5446967Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5450216Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5453159Z    at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
2021-07-05T08:40:47.5454481Z    at Consul.Lock.<Acquire>d__24.MoveNext()
2021-07-05T08:40:47.5455274Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5456849Z    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
2021-07-05T08:40:47.5458296Z    at Consul.Lock.<Acquire>d__24.MoveNext()
2021-07-05T08:40:47.5459134Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5460803Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5463999Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5466804Z    at Consul.Test.LockTest.<>c__DisplayClass3_0.<<Lock_OneShot>b__0>d.MoveNext() in D:\a\consuldotnet\consuldotnet\Consul.Test\LockTest.cs:line 123
2021-07-05T08:40:47.5468100Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5469839Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5473044Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5475243Z ----- Inner Stack Trace -----
2021-07-05T08:40:47.5475855Z    at Consul.GetRequest`1.<Execute>d__10.MoveNext()
2021-07-05T08:40:47.5476695Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5478379Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5481617Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5483825Z    at Consul.KV.<Get>d__13.MoveNext()
2021-07-05T08:40:47.5484606Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5486514Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5489911Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5492919Z    at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
2021-07-05T08:40:47.5494263Z    at Consul.Lock.<Acquire>d__24.MoveNext()
2021-07-05T08:40:47.5495079Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5496798Z    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
2021-07-05T08:40:47.5498141Z    at Consul.Lock.<Acquire>d__24.MoveNext()
2021-07-05T08:40:47.5498924Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5501778Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5506072Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
2021-07-05T08:40:47.5509579Z    at Consul.Test.LockTest.<>c__DisplayClass3_0.<<Lock_OneShot>b__0>d.MoveNext() in D:\a\consuldotnet\consuldotnet\Consul.Test\LockTest.cs:line 123
2021-07-05T08:40:47.5510921Z --- End of stack trace from previous location where exception was thrown ---
2021-07-05T08:40:47.5512793Z    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
2021-07-05T08:40:47.5516539Z    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

And here are the relevant lines from the Consul agent logs:

2021-07-05T08:40:46.277Z [DEBUG] agent.http: Request finished: method=PUT url=/v1/session/create from=127.0.0.1:50340 latency=0s
2021-07-05T08:40:46.280Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?wait=1s from=127.0.0.1:50340 latency=0s
2021-07-05T08:40:46.281Z [DEBUG] agent.http: Request finished: method=PUT url=/v1/kv/test/lock/oneshot?flags=3304740253564472344&acquire=86221ea7-1a48-d137-de1e-2e523f8b147d from=127.0.0.1:50340 latency=0s
2021-07-05T08:40:46.284Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?consistent from=127.0.0.1:50340 latency=0s
2021-07-05T08:40:46.285Z [DEBUG] agent.http: Request finished: method=PUT url=/v1/session/create from=127.0.0.1:50341 latency=998.9ยตs
2021-07-05T08:40:46.286Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?wait=1s from=127.0.0.1:50341 latency=0s
2021-07-05T08:40:47.285Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?index=313&wait=999ms from=127.0.0.1:50341 latency=999.433ms
2021-07-05T08:40:47.286Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?index=313&wait=ms from=127.0.0.1:50341 latency=0s
2021-07-05T08:41:16.279Z [DEBUG] agent.http: Request finished: method=GET url=/v1/kv/test/lock/oneshot?consistent&index=313 from=127.0.0.1:50340 latency=29.9922598s

The next to last line is indeed specifying an invalid wait time: wait=ms.

Expected behavior

We should never specify an invalid wait time.

Plans to publish to Nuget.org?

This repo appears to have the most commits since PlayFab archived their project. Do you have plans to publish to nuget - do you need help with doing that?

Unnecessary delay in LockTryOnce scenario

Currently if we are using single shot locking strategy and creating Lock with LockTryOnce = true option, in case of negative locking result we have to wait for LockRetryTime, before the checking for LockTryOnce and loop brake.
I suppose it would be great to check for value of LockTryOnce before introducing a delay.

Bad package version in Nuget

Hi there!

It looks like the latest package that was uploaded to nuget 13 days ago breaks nuget installation/resolution as it has a file version number of 0.0.0.0.

The assembly has a full name of Consul, Version=0.0.0.0, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95.

1.6.10.2 at the top, 1.6.10.1 at the bottom
image

Note that version 1.6.10.1 has a file version of 1.6.1.1 which appears to be the last stable release in Nuget.

I'd suggest perhaps de-listing these packages so that people who depend on them don't break when upgrading.

Thanks!

[CI Bug]: Consul.Test.TokenTest.Token_CreateWithServiceIdentitiesDelete is flaky

Describe the bug

Failed run: https://github.com/G-Research/consuldotnet/runs/7801200863?check_suite_focus=true

2022-08-12T06:33:42.4254439Z [xUnit.net 00:00:16.15]     Consul.Test.TokenTest.Token_CreateWithServiceIdentitiesDelete [FAIL]
2022-08-12T06:33:42.5252849Z ##[error]Consul.Test.TokenTest.Token_CreateWithServiceIdentitiesDelete: Assert.Equal() Failure
2022-08-12T06:33:42.5254795Z   Failed Consul.Test.TokenTest.Token_CreateWithServiceIdentitiesDelete [7 ms]
2022-08-12T06:33:42.5255486Z   Error Message:
2022-08-12T06:33:42.5255930Z    Assert.Equal() Failure
2022-08-12T06:33:42.5259311Z                                  โ†“ (pos 30)
2022-08-12T06:33:42.5260255Z Expected: ยทยทยทdummyserviceidentityone
2022-08-12T06:33:42.5261005Z Actual:   ยทยทยทdummyserviceidentitytwo
2022-08-12T06:33:42.5261671Z                                  โ†‘ (pos 30)
2022-08-12T06:33:42.5262104Z   Stack Trace:
2022-08-12T06:33:42.5262995Z      at Consul.Test.TokenTest.Token_CreateWithServiceIdentitiesDelete() in /home/runner/work/consuldotnet/consuldotnet/Consul.Test/TokenTest.cs:line 181
2022-08-12T06:33:42.5264168Z --- End of stack trace from previous location ---
2022-08-12T06:37:46.4630756Z 
2022-08-12T06:37:46.4733716Z Failed!  - Failed:     1, Passed:   163, Skipped:    10, Total:   174, Duration: 4 m 18 s - /home/runner/work/consuldotnet/consuldotnet/Consul.Test/bin/Release/net6.0/Consul.Test.dll (net6.0)
2022-08-12T06:37:46.4943458Z 
2022-08-12T06:37:46.4943887Z Build FAILED.
2022-08-12T06:37:46.4946302Z     0 Warning(s)
2022-08-12T06:37:46.4948207Z     0 Error(s)

Steps To Reproduce

Expected behavior

Environment

Logs

consul-logs-1.13.1-net6.0-ubuntu-18.04.zip

Additional context

No response

the problems of service register

Describe the bug

Hello๏ผŒI want to register the service to consul by calling the "IAgentEndpoint.Agent.ServiceRegister",this is my code:

 m_consulClient = new ConsulClient();
            return Task.Run(async () =>
            {
                try
                {
                    await m_consulClient.Agent.ServiceRegister(new AgentServiceRegistration()
                    {
                        ID = Guid.NewGuid().ToString(),
                        Name = Name,
                        Port = SOCKET_SERVER_PORT,
                        Check = new AgentCheckRegistration()
                        {
                            ID = Name,
                            Name = $"{Name} Status",
                            ServiceID = Name,
                            Notes = $"Registered {DateTime.Now}",
                            Status = HealthStatus.Passing,
                            TTL = TimeSpan.FromSeconds(30),
                        }
                    }, m_disposeTokenSource.Token);

                    _logger.Debug($"Register {Name} Succesed");
                    m_registerToConsul = true;
                    m_timer.Elapsed += TimerOnElapsed;
                    m_timer.Start();
                }
                catch (Exception e)
                {
                    _logger.Error(e);
                }

I used consul_server vesion 1.4 to register is sucessed,but uesd consul_server vesion 1.7 to register something is wrong,the exception is

Consul.ConsulRequestException: Unexpected response, status code BadRequest: Request decode failed: json: unknown field "ID"
   at Consul.PutRequest`1.Execute(CancellationToken ct)
   ****.StartupComponents.AgentServiceRegistInitialize.<InitializeAsync>b__10_0()

What do I need to do to solve the problem. Best wishes.

Steps To Reproduce

Expected behavior

Logs

Environment

  • OS: [Windows] [Linux]
  • Consul Version: [1.4.2] [1.7.2]
  • consultdotnet Version: [1.6.1.1]

Additional context

Failure to run test on Windows with net461 TFM

Describe the bug

There is a problem when running Consul.Test on Windows with net461 TFM. Fine with netcoreapp2.1 (which the CI uses).

Steps To Reproduce

Just run the test in VS or CLI on master.

Expected behavior

Tests pass just like with the net core TFM.

Logs

FileLoadException for Newtonsoft.Json for almost all tests.

Example:

Message: 
    System.IO.FileLoadException : Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
  Stack Trace: 
    ConsulClient.ctor(Action`1 configOverride, Action`1 clientOverride, Action`1 handlerOverride)
    ConsulClient.ctor(Action`1 configOverride) line 384
    ACLTest.ctor() line 33

Environment

  • OS: Windows
  • Consul Version: Latest
  • consultdotnet Version Latest

Consul.AspNetCore NuGet package naming collision issue

The Consul.AspNetCore nuget package cannot be found on NuGet.org. There's already a package with this name there, but it's not yours, it's been published by zlzforever in 2018. You can find the package here: Consul.AspNetCore

Though I think your CI/CD pipeline tried to publish your package, since you are listed as the owner of the package too. I'm not sure how the nuget.org package repository is configured, I suppose it didn't accept your package due to the name collision, but added you as the owner of the already existing package.

Is it possible to remove the dependecy on Newtonsoft.Json?

Hello,

I am using your library to register my services for my API gateway without issues, but I noticed that it still has a reference to Newtonsoft.Json as the only library I use.
Would it be possible to switch to System.Text.Json serializers?

Regards

the result of query service need more than one second

Describe the bug

I query the service result by consulClient,
this spend more than one second

Steps To Reproduce

Expected behavior

Logs

Environment

  • OS: windows 10
  • Consul Version: 1.6.10.1
  • consultdotnet Version 5.0

Additional context

var query = consulClient.Health.Service(serviceName);
var entryArray = query.Result.Response; // more than one second here

Support access to Connect services

One of the major features and offerings by Consul is the Connect service-mesh that provides secure communication between services. Both the HTTP API as well as the GO API provide a way to find these Connect services via the Catalog endpoint / object and would be very useful for dotnet apps trying to use these concepts as well.

https://www.consul.io/api/catalog#list-nodes-for-connect-capable-service
https://pkg.go.dev/github.com/hashicorp/consul/api#Catalog.Connect

I will be working on a PR for this if it's not already on someone's list as it's needed by my employer, but input would be very appreciated!

Missing dependency with 4.6.1 library

We are attempting to use the .Net Framework 4.6.1 library in a .Net Framework 4.6.2.

When we install version 0.7.2.6, all works as expected.

When we install version 1.6.1, the following problems occur:

  1. Visual Studio does not recognise the package dll properly (there is a yellow triangle on the references tab)

  2. Fixing 1 above by manually including the assembly, running a console app gives:

System.IO.FileNotFoundException
  HResult=0x80070002
  Message=Could not load file or assembly 'Consul.dll, Version=1.6.1.0, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95' or one of its dependencies. The system cannot find the file specified.
  Source=<Cannot evaluate the exception source>
  StackTrace:

So far I cannot tell what is the real problem here - not too clued up on nuget packages and VS is not showing what it doesn't like. I used IL Spy, but can't tell the missing dependency, so I surmise that the 4.6.1 assembly is not built correctly...

Our console application is really simple:

    class Program
    {
        static void Main(string[] args)
        {
            var consulClient = new ConsulClient(consulConfig =>
            {
                var address = "http://localhost.consul-server";
                consulConfig.Address = new Uri(address);
            });
            var services = consulClient.Agent.Services().Result.Response;
        }
    }

Using version 0.7.2.6, the services show the services correctly.

Wrong type

public Dictionary<string, ServiceTaggedAddress> ServiceTaggedAddresses { get; set; }

I think this should be IDictionary instead of Dictionary. Same for the lines: 34 and 61.

Configuring Port as part of Service Registration

I need to configure a dynamic port as part of my service registration during a generic host startup sequence. According to the dotnet docs, if you say your binding port is "0", then it'll allocate a dynamic port for you. My problem is how do I do this within the registration apis?

Filter Agent Services on ServiceName?

What can we do to filter agent services on ServiceName? ATM all services are returned to loop on them.
Consul api provides filtering on properties so looking to filter on consul's end itself to improve performance.

Thanks,
Nikhil

[Bug]: System.IO.IOException: The response ended prematurely

Describe the bug

during parallel calling the below function, .Health.Service method crashed

        public async Task<List<AgentService>> GetHealthyServiceInstancesAsync(string serviceName)
        {
            var t = await _consul.Health.Service(serviceName);

            var addresses = new List<string>();

            var services = new List<AgentService>();

            foreach (var serviceEntry in t.Response)
            {
                foreach (var check in serviceEntry.Checks)
                {
                    if (check.Status.Status != HealthStatus.Passing.Status) continue;
                    if (addresses.Contains(serviceEntry.Service.Address)) continue;
                    services.Add(serviceEntry.Service);
                    addresses.Add(serviceEntry.Service.Address);
                }
            }
            return services;

        }

Steps To Reproduce

  public class AnyClass
  {
              await 1000Elements.AsyncParallelForEach(async element =>
             {
                 // ProcessAsync is a method calling GetHealthyServiceInstancesAsync
                 await ProcessAsync(element);
              }
  }


  public static class IEnumerableExtensions
  {
      // code from
      // https://medium.com/@alex.puiu/parallel-foreach-async-in-c-36756f8ebe62
      // https://scatteredcode.net/parallel-foreach-async-in-c/
      // reference(difference between parallel.foreach and task.wait all)
      // https://stackoverflow.com/questions/19102966/parallel-foreach-vs-task-run-and-task-whenall
      public static async Task AsyncParallelForEach<T>(this IAsyncEnumerable<T> source, Func<T, Task> body, int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded, TaskScheduler scheduler = null)
      {
          var options = new ExecutionDataflowBlockOptions
          {
              MaxDegreeOfParallelism = maxDegreeOfParallelism
          };
          if (scheduler != null)
              options.TaskScheduler = scheduler;
          var block = new ActionBlock<T>(body, options);
          await foreach (var item in source)
              block.Post(item);
          block.Complete();
          await block.Completion;
      }

      public static Task AsyncParallelForEach<T>(this IEnumerable<T> source, Func<T, Task> body, int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded, TaskScheduler scheduler = null)
              {
                  var options = new ExecutionDataflowBlockOptions
                  {
                      MaxDegreeOfParallelism = maxDegreeOfParallelism
                  };
                  if (scheduler != null)
                      options.TaskScheduler = scheduler;

                  var block = new ActionBlock<T>(body, options);

                  foreach (var item in source)
                      block.Post(item);

                  block.Complete();
                  return block.Completion;
      }

  }

Expected behavior

should not crash

Environment

  • OS: 3.10.0-693.el7.x86_64
  • Consul Version: Consul v1.8.0
  • consultdotnet Version : 1.6.10.7

Logs

2023-08-18 17:44:54.509 +08:00 [ERR] [Microsoft.Extensions.Hosting.Internal.Host] BackgroundService failed
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The response ended prematurely.
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage, Boolean, CancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage, Boolean, CancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage, Boolean, Boolean, CancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage, Boolean, CancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage, HttpCompletionOption, CancellationTokenSource, Boolean, CancellationTokenSource, CancellationToken)
at Consul.GetRequest`1.Execute(CancellationToken ct)
at DBAInternalCommon.Services.ConsulService.GetHealthyServiceInstancesAsync(String serviceName)
at DBAInternalCommon.Helpers.DBAInternalServiceHelper.FetchServiceHealthAddressAsync(String serviceName)

Additional context

No response

Improvement: fix naming rule violation

In VS

Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Agent.cs	618	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461)	C:\consuldotnet\Consul\Client.cs	275	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: passingStatus	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Agent.cs	35	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: warningStatus	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Agent.cs	36	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: criticalStatus	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Agent.cs	37	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Agent.cs	619	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	44	Active
Error	IDE1006	Naming rule violation: Prefix '_' is not expected	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	46	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	270	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	271	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	317	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	363	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	373	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	482	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Client_Request.cs	62	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: passing	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Health.cs	33	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: warning	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Health.cs	34	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: critical	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Health.cs	35	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: maintenance	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Health.cs	36	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: any	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\Health.cs	37	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvSetOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	72	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvDeleteOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	73	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvDeleteCASOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	74	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvDeleteTreeOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	75	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvCASOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	76	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvLockOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	77	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvUnlockOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	78	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvGetOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	79	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvGetTreeOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	80	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvCheckSessionOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	81	Active
Error	IDE1006	Naming rule violation: These words must begin with upper case characters: kvCheckIndexOp	Consul (net461), Consul (netstandard2.0)	C:\consuldotnet\Consul\KV.cs	82	Active
Error	IDE1006	Naming rule violation: Missing prefix: '_'	Consul (netstandard2.0)	C:\consuldotnet\Consul\Client.cs	273	Active
Error	IDE1006	Naming rule violation: Prefix '_' is not expected	Consul.Test (net461), Consul.Test (net5.0), Consul.Test (netcoreapp2.1), Consul.Test (netcoreapp3.1)	C:\consuldotnet\Consul.Test\TestHelper.cs	29	Active
Error	IDE1006	Naming rule violation: Prefix '_' is not expected	Consul.Test (net461), Consul.Test (net5.0), Consul.Test (netcoreapp2.1), Consul.Test (netcoreapp3.1)	C:\consuldotnet\Consul.Test\TimeoutUtils.cs	71	Active

Is the class ConsulClient thread safe?

I'm not sure if this is the correct place for this question, if it is not I apologize in advance.

I did not find any documentation about the thread safety of ClientConsul class.
Can we have only one instance of ClientConsul and share this instance between multiple tasks querying and writing concurrently to the KV store, or should create a new instance for every operation whith the KV store?.

Thank you.

Table showing missing features in consuldotnet

This table shows missing and supported APIs in Consuldotnet compared to the golang client (1.8.19)
@marcin-krystianc @naskio

Group Endpoint Route Status
Agent-Base List Members GET /v1/agent/members yes
Read Configuration GET /v1/agent/self yes
Reload Agent PUT /v1/agent/reload yes
Enable Maintenance Mode PUT /v1/agent/maintenance yes
Join Agent GET /v1/agent/join/:id yes
Graceful Leave + Shutdown PUT /v1/agent/leave yes
Agent Host "GET", "/v1/agent/host" yes
Agent Version "GET", "/v1/agent/version" yes
Agent Metrics "GET", "/v1/agent/metrics" Yes
Agent Metric Stream "GET", "/v1/agent/metrics/stream"
Trigger configuration Reload for Agent "PUT", "/v1/agent/reload" yes
Agent Health By Service Id "GET", /v1/agent/health/service/id/:id yes
Agent Health By Service Name "GET", "/v1/agent/health/service/name/:name" yes
ForceLeave "PUT", "/v1/agent/force-leave/:node yes
ConnectAuthorize "POST", "/v1/agent/connect/authorize"
EnableorDisableServiceMaintenance "PUT", "/v1/agent/service/maintenance/:serviceId yes
EnableorDisableNodeMaintenance "PUT", "/v1/agent/maintenance" yes
ConnectCARoots "GET", "/v1/agent/connect/ca/roots" yes
Get Agent Logs "GET", "/v1/agent/monitor" yes
UpdateTokenOnce "PUT", "/v1/agent/token/:target" yes
Agent-Checks List Checks GET /v1/agent/checks yes
Update TTL (Legacy) "PUT", "/v1/agent/check/:status/:id" yes
Register Check PUT /v1/agent/check/register yes
Deregister Check PUT /v1/agent/check/deregister/:id yes
TLL Check Pass GET /v1/agent/check/pass/:id yes
TTL Check Warn GET /v1/agent/check/warn/:id yes
TLL Check Fail GET /v1/agent/check/fail/:id yes
TLL Check Update GET /v1/agent/check/update/:id yes
Agent - Services List Services GET /v1/agent/services yes
Register Service PUT /v1/agent/service/register yes
Deregister Service PUT /v1/agent/service/deregister/:id yes
Enable Maintenance Mode PUT /v1/agent/service/maintenance/:id yes
Return a locally registered service instance "GET", "/v1/agent/service/:serviceId" yes
Catalog List Datacenters "GET /v1/catalog/datacenters" yes
List Nodes in a given DC GET /v1/catalog/nodes yes
List Services in a given DC GET /v1/catalog/services yes
List Nodes for Service GET /v1/catalog/service/:id yes
List Nodes for Mesh Capable Service GET /v1/catalog/connect/:id yes
List Services for Node GET /v1/catalog/node/:id yes
Register a new Catalog Item "PUT", "/v1/catalog/register" yes
Deregister existing Catalog Item "PUT", "/v1/catalog/deregister") yes
NodeServiceList "GET", "/v1/catalog/node-services/:node" yes
GateWayServices "GET", "/v1/catalog/gateway-services/:gateway"
Coordinates Read WAN Coordinates GET /v1/coordinates/datacenters yes
Read LAN Coordinates GET /v1/coordinates/nodes yes
Update LAN Coordinates "PUT", "/v1/coordinate/update"
Coordinates of a single node "GET", "/v1/coordinate/node/:node" yes
Events Fire Event PUT /v1/event/fire/:name yes
List Events GET /v1/event/list yes
Health List Checks for Node "GET /v1/health/node/:id" yes
List Checks for Service GET /v1/health/checks/:id yes
List Nodes for Service GET /v1/health/service/:id yes
List Checks in State GET /v1/health/state/:state yes
List Ingress Health for Service GET "/v1/health/ingress/:service"
List Health for Mesh Enables Services "/v1/health/connect/:service" yes
KV Store Read Key "GET /v1/kv/:key" yes
Create/Update Key PUT /v1/kv/:key yes
Delete Key DELETE /v1/kv/:key yes
Namespace List Namespaces GET /v1/namespaces yes
Read Namespace GET /v1/namespace/:name yes
Create Namespace PUT /v1/namespace yes
Update Namespace PUT /v1/namespace/:name yes
Delete Namespace DELETE /v1/namespace/:name yes
Session List GET /v1/session/list yes
Create POST /v1/session/create yes
Destroy PUT /v1/session/destroy/:id yes
Renew PUT /v1/session/renew/:id yes
Info GET /v1/session/info/:id yes
Node GET /v1/session/node/:node yes
Status Leader GET /v1/status/leader yes
Peers GET /v1/status/peers yes
Transaction Transaction PUT /v1/txn yes
DiscoveryChain Retrieve a compiled discovery chain GET /v1/discovery-chain/:name
Evaluate and compile a discovery Chain POST /v1/discovery-chain/:name
Config Retrieve a specific configuration by kind and name GET /v1/config/{kind}/{name} yes
List all configuration entries of a specific kind GET /v1/config/{kind} yes
Set a new configuration entry PUT /v1/config yes
Delete a specific configuration entry by kind and name DELETE /v1/config/{kind}/{name} yes

[Bug]: Consul.Test.SemaphoreTest.Semaphore_OneShot is flaky

Describe the bug

Failed run (unfortunately, this is not the only instance of this): https://github.com/G-Research/consuldotnet/actions/runs/4490644576/jobs/7898021860

[xUnit.net 00:05:08.97]     Consul.Test.SemaphoreTest.Semaphore_OneShot [FAIL]
Error: Consul.Test.SemaphoreTest.Semaphore_OneShot: System.OperationCanceledException : Timeout waiting for task to complete
  Failed Consul.Test.SemaphoreTest.Semaphore_OneShot [5 m 2 s]
  Error Message:
   System.OperationCanceledException : Timeout waiting for task to complete
  Stack Trace:
     at Consul.Test.TimeoutUtils.<WithTimeout>d__1.MoveNext() in D:\a\consuldotnet\consuldotnet\Consul.Test\TimeoutUtils.cs:line 66
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Consul.Test.SemaphoreTest.<Semaphore_OneShot>d__4.MoveNext() in D:\a\consuldotnet\consuldotnet\Consul.Test\SemaphoreTest.cs:line 122
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

Failed!  - Failed:     1, Passed:   171, Skipped:     4, Total:   176, Duration: 6 m 19 s - Consul.Test.dll (net[46](https://github.com/G-Research/consuldotnet/actions/runs/4490644576/jobs/7898021860#step:9:47)1)

Steps To Reproduce

I think it is random occurrence

Expected behavior

Test shouldn't fail

Environment

  • Consul Version: 1.10.12

Logs

No response

Additional context

No response

[Bug]: ServiceRegister does not pass WriteOptions to PutRequest, resulting in missing token and datacenter

Describe the bug

When using the ServiceRegister method in the Consul.NET library, the WriteOptions are not passed to the PutRequest. As a result, the token and datacenter information are not included in the request, leading to potential issues with authentication and handling requests in the correct datacenter.

Example Configuration

image

Output

Because of the described behavior, PutRequest.Options has no token and no datacenter provided.

image

However, the configuration appears to be correct.

image

Steps To Reproduce

  1. Create a ConsulClient instance with a valid token and datacenter configuration.
  2. Register a service using the `ServiceRegister method.
  3. Observe that the token and datacenter are not included in the request sent to the Consul agent.

Expected behavior

The ServiceRegister method should pass the WriteOptions containing the token and datacenter information to the `PutRequest, so that they are included in the request sent to the Consul agent.

Environment

  • OS: Linux, Mac
  • Consul Version: 1.14.2
  • consultdotnet Version: 1.6.10.8

Logs

No response

Additional context

Proposed Solution

To address the issue, the ServiceRegister method in the Consul.NET library can be modified to pass the WriteOptions from the client's configuration.

public Task<WriteResult> ServiceRegister(
    AgentServiceRegistration service,
    bool replaceExistingChecks,
    CancellationToken ct = default (CancellationToken))
{
    PutRequest<AgentServiceRegistration> putRequest = this._client.Put<AgentServiceRegistration>("/v1/agent/service/register", service, this._client.Config.WriteOptions);
    if (replaceExistingChecks)
        putRequest.Params["replace-existing-checks"] = "true";
    return putRequest.Execute(ct);
}

Current Workaround:

A workaround for the issue is to create a subclass of the ConsulClient and create a new CustomConsulClient. This workaround depends on Consul ACL and policy configuration.

using System.Reflection;
using Consul;

namespace BuildingBlocks.Common.Subclasses;

public class CustomConsulClient : ConsulClient
{
    public CustomConsulClient(ConsulClientConfiguration config, HttpClient client)
        : base(config, client)
    {
    }

    public new Task<WriteResult> ServiceRegister(
        AgentServiceRegistration service,
        bool replaceExistingChecks = false,
        CancellationToken ct = default)
    {
        var putMethod = GetType()
            .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
            .Where(x => x.Name == "Put")
            .ToList()[0];

        // Create a generic version of the Put method for AgentServiceRegistration
        var putGenericMethod = putMethod.MakeGenericMethod(typeof(AgentServiceRegistration));

        var writeOptions = new WriteOptions { Token = Config.Token, Datacenter = Config.Datacenter };

        // Call the internal Put<TIn> method with the appropriate parameters
        var putRequest = (PutRequest<AgentServiceRegistration>)putGenericMethod.Invoke(this, new object[] { "/v1/agent/service/register", service, writeOptions });

        return putRequest.Execute(ct);
    }
}

To use the CustomConsulClient, replace ConsulClient with `CustomConsulClient as shown below:

var consulClient = new CustomConsulClient(consulConfig,httpClient);
consulClient.ServiceRegister(serviceRegistration).Wait();

instead of:

var consulClient = new ConsulClient(consulConfig,httpClient);
consulClient.Agent.ServiceRegister(serviceRegistration).Wait();

[Bug]: Can Upgrade the Newtonsoft.Json to fix CWE-755?

Describe the bug

Introduced through
[email protected]
Fixed in
[email protected]
Exploit maturity
PROOF OF CONCEPT
Show less detail
Detailed paths
Introduced through: project@* โ€บ [email protected] โ€บ [email protected]
Fix: No remediation path available.
Overview
Affected versions of this package are vulnerable to Insecure Defaults due to improper handling of StackOverFlow exception (SOE) whenever nested expressions are being processed. Exploiting this vulnerability results in Denial Of Service (DoS), and it is exploitable when an attacker sends 5 requests that cause SOE in time frame of 5 minutes.

Note: This vulnerability affects IIS Applications.

Steps To Reproduce

A security problem.

Expected behavior

Upgrade the Newtonsoft.Json to 13.0.1 can fix it.

Environment

  • OS: win 11
  • Consul Version:
  • consultdotnet Version consul1.6.10.6

Logs

No response

Additional context

No response

Support for injecting HttpClient in a non-obsolete constructor

As of now ConsulClient allows for injecting an HttpClient using an [Obsolete] constructor (here). This project should remove this [Obsolete] attribute until an alternative way to inject HttpClient is provided as a migration path (my suggestion is sticking with the current constructor or just a Func<HttpClient>). As of now the non-obsolete constructors carry the issue that they internally manage an HttpClient, which means that you either dispose ConsulClient and risk socket exhaustion, or you use a singleton ConsulClient and risk dealing with a stale DNS (see here). My personal opinion is that ConsulClient should not be managing HttpClient lifetimes at all since they hide serious issues from the library user.

Add ASP.NET Core integration

  • Add IServiceCollection extensions for registering client
  • Add IHostedService or IApplicationBuilder extensions for service register/deregister

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.