Giter Site home page Giter Site logo

man-group / dapr-sidekick-dotnet Goto Github PK

View Code? Open in Web Editor NEW
174.0 23.0 21.0 395 KB

Dapr Sidekick for .NET - a lightweight lifetime management component for Dapr

License: Apache License 2.0

C# 100.00%
dapr dotnet csharp dotnet-core dotnet-framework dotnet-standard

dapr-sidekick-dotnet's Introduction

Dapr Sidekick for .NET

Build Status codecov Maintainability License: MIT Follow on Twitter

Dapr Sidekick for .NET is a control plane component that makes adding Dapr to your solutions frictionless. It simplifies the development and operations of distributed .NET applications that use Dapr by providing lifetime management, core service invocation and improved debugging experiences across a wide range of .NET platforms and development tools. While it does not require the official Dapr SDK for .NET it is complementary and designed to work alongside it.

Key features:

  • Discovers, configures and launches the Dapr Sidecar process (daprd) with automatic port assignment
  • Monitors and relaunches the Dapr Sidecar on unexpected exit
  • Dapr command-line arguments exposed via the Microsoft Extensions Configuration Framework
  • Routes Dapr stdout log messages to the Microsoft Extensions Logging Framework
  • Consolidates Dapr health check and metrics endpoints into ASP.NET Core endpoints
  • Seamless debugging experience within Visual Studio and other .NET development tools
  • Compatible with all versions of .NET from .NET Framework 3.5 to .NET 5.0
  • Supports Sidecar, Placement and Sentry processes

Dapr Community Call

A presentation of Dapr Sidekick for .NET was given to the Dapr community as part of Community Call 39, demonstrating its ability to easily integrate the Dapr sidecar into an ASP.NET Core application and enable seamless debugging sessions with Visual Studio 2019. Watch the 20-minute segment on YouTube to get started as quickly as possible.

Samples

Visit the samples folder for examples of how you can get up and running with Dapr Sidekick.

Getting Started

Dapr Sidekick requires a local installation of Dapr, the recommended approach is to follow the Install Dapr CLI and Init Dapr Locally steps in the official Dapr Docs.

By default the dapr init command will install additional development components such as a Redis docker container. If you do not need these you can instead initialize Dapr using the slim init mode command dapr init --slim.

Once Dapr is installed, Dapr Sidekick can be used to manage the Dapr Sidecar runtime process daprd. For example, in an ASP.NET Core application add the Man.Dapr.Sidekick.AspNetCore NuGet package to the project file:

<ItemGroup>
  <PackageReference Include="Man.Dapr.Sidekick.AspNetCore" Version="1.1.0" />
</ItemGroup>

Next modify the ConfigureServices method in Startup.cs as follows:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // Add Dapr Sidekick
    services.AddDaprSidekick(Configuration);
}

That's it! When you run the application Dapr Sidekick will discover the Dapr sidecar in the default installation folder, dynamically assign all required ports then launch and manage the lifetime of the runtime process. Detailed diagnostic log messages from both Dapr Sidekick and the Dapr sidecar are pumped through the standard Microsoft Extensions Logging framework. When the application is terminated Dapr Sidekick will shut down the Dapr sidecar.

Dapr Sidekick includes extensive configuration options for the Dapr Sidecar, Placement and Sentry processes - see the Options code for for more details.

Building the repository

This repository builds the following packages:

Package Description Compatibility
Man.Dapr.Sidekick Core features .NET Framework 3.5+, .NET Standard 2.0, .NET Core 3.1, .NET 5.0
Man.Dapr.Sidekick.AspNetCore ASP.NET Core extensions .NET Framework 4.6.2+, .NET Standard 2.0, .NET Core 3.1, .NET 5.0
Man.Dapr.Sidekick.Extensions.Logging Integrations for Microsoft Extensions Logging .NET Framework 4.5+, .NET Standard 2.0, .NET Core 3.1, .NET 5.0

Prerequisites

Each project in this repository is a normal C# project. We recommend building on Windows, where at a minimum you need the .NET 5.0 SDK to build, test, and generate NuGet packages.

We also recommend installing the latest Visual Studio 2019 which will set you up with all the .NET build tools and allow you to open the solution files. Community Edition is free and can be used to build everything here.

Make sure you update Visual Studio to the most recent release.

Build Process

To build everything and generate NuGet packages, run dotnet cli commands from <RepoRoot>. Binaries and NuGet packages will be dropped in <RepoRoot>/bin.

# Build Dapr Sidekick and tests
dotnet build -c Debug  # for release, -c Release

# Run unit tests
dotnet test

# Generate nuget packages in /bin/Debug
dotnet pack

<RepoRoot> is the path where you cloned this repository.

Each project can also be built individually directly through the CLI or your editor/IDE. You can open the solution file all.sln in <RepoRoot> to load all projects at once.

Nuget packages are dropped under <RepoRoot>/bin/<Debug|Release>/nugets when you build locally.

External dependencies

In order to target as many possible .NET platforms as possible with minimal external dependencies, Dapr Sidekick gratefully includes source code from a number of external open-source projects. Where appropriate code files are annotated with the original source link and LICENSE file included. The following are the main sources of external code:

Name License Local Source
Dapr SDK for .NET MIT DaprClient
.NET Extensions 2.1 Apache 2.0 Logging
Prometheus .NET MIT Metrics

Dapr Sidekick also includes a package reference to Newtonsoft Json.NET for parsing JSON log messages from Dapr.

Non-Windows Platforms

On platforms other than Windows (such as Linux and Mac OS) some features of Dapr Sidekick may not be available due to the required native API calls not being available. These include:

Feature Platforms Notes
Attach to existing instance Linux/Mac OS Will not detect existing daprd instance for same AppId and Port

Acknowledgements

Dapr Sidekick has been under active development at Man Group since 2020.

Original concept and implementation: Simon Jones

Contributors:

Contributions welcome! Please review the Contribution Guidelines.

License

Dapr Sidekick is licensed under Apache 2.0, a copy of which is included in LICENSE.

dapr-sidekick-dotnet's People

Contributors

a-elsheikh avatar attilaszasz avatar badgeratu avatar iliasp91 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

dapr-sidekick-dotnet's Issues

DaprSidekick appsetting section ignored?

Hello - first of all, thanks for all the great work on this project!

I'm trying to configure DaprSidekick with a custom components folder. For that I tried adding the config:
{ "DaprSidekick": { "ComponentsDirectory": "dapr-components" } }

I tried initializing using
builder.Services.AddDaprSidekick();
and
builder.Services.AddDaprSidekick(builder.Configuration);

Both times the setting are ignored and the components are taken from the default dapr installation folder. Are there anything I'm missing here, or it a bug?

EDIT: After some debugging I got it working by using the alternative AddDaprSidekick method (not using appsettings):
builder.Services.AddDaprSidekick(delegate(DaprOptions options) { options.Sidecar ??= new DaprSidecarOptions(); options.Sidecar.ComponentsDirectory = "dapr-components"; });

Of course I'd still very much like to have it working with appsettings.json instead.

Configuration section should be named DaprSidekick not Dapr

Expected Behavior

Sidekick settings should be loaded from a configuration section in appsettings.json called something other than "Dapr".

Actual Behavior

At present Sidekick settings are loaded from a configuration section in appsettings.json called "Dapr", for example:

{
  "Dapr": {
    "RuntimeDirectory": "dapr",
    "mTLS": true,
    "Enabled": false
  }
 }

This is a little misleading as it looks like these configuration settings are for "Dapr" itself, whereas they are actually for the Sidekick management component. Also this section name could potentially be used by the official Dapr SDK in the future. It should therefore be changed to something like "DaprSidekick".

Suggest supporting both initially by attempting to map to the section "DaprSidekick" first, and then falling back to the section "Dapr" if it does not exist. Perhaps deprecate the "Dapr" option in Sidekick release 2.0 in the future.

Help?

Where does one go for help on Sidekick? There are no active questions on Stackoverflow, is there are Usergroup or other where questions can be asked and the good folks who build Sidekick hang out to help us plebs out?

Thanks.

Documentation

Hi!

There is some documentation that explain how get logs from daprd runned by sidekick or how customize port to use by daprd?

Thanks at all.

Health, Metrics and Status information is not available When Sidekick Enabled=false

How can I use Sidekick just for monitoring and metrics using an existing Dapr Sidecar?

I would like to be able to use Dapr Sidekick for health, status and metrics only but avoid launching a Sidecar process.

In other words, is there an option that I can use to just get everything Sidekick offers except for launching the Sidecar process?

Current behaviour

When setting DaprSidekick.Enabled = false all functionality gets disabled (HealthCheck, Dapr Status, Metrics)
appsettings.json

{
  "DaprSidekick": {
    "Enabled": false
  }
}

Health API

{
  "status": "Healthy",
  "totalDuration": "00:00:00.0014793",
  "entries": {
    "dapr-sidecar": {
      "data": {
        
      },
      "description": "Dapr process 'daprd' not available, status is Disabled",
      "duration": "00:00:00.0000316",
      "status": "Healthy",
      "tags": [
        
      ]
    }
  }
}

Dapr Status

{
  "process": {
    "name": "daprd",
    "status": "Disabled",
    "isRunning": false,
    "isAttached": false,
    "description": "Dapr process 'daprd' not available, status is Disabled"
  }
}

Unable to load shared library 'kernel32.dll' on macOS

Expected Behavior

Starting more than a single dapr-service via dapr-sidekick should be possible on macOS

Actual Behavior

Starting a single service seems to work, starting a second one results in this error message:

System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(libkernel32.dll, 1): image not found
   at Man.Dapr.Sidekick.Native.NativeProcess.OpenProcess(OpenProcessDesiredAccessFlags dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId)
   at Man.Dapr.Sidekick.Native.NativeProcess.GetCommandLine(Process process, String& commandLine)
   at Man.Dapr.Sidekick.Process.ProcessCommandLine..ctor(SystemProcess systemProcess)
   at Man.Dapr.Sidekick.Process.SystemProcess.GetCommandLine()
   at Man.Dapr.Sidekick.Process.DaprProcess`1.CheckExistingProcesses(TOptions proposedOptions)
   at Man.Dapr.Sidekick.Process.DaprProcess`1.Initialize(DaprCancellationToken cancellationToken)

Steps to Reproduce the Problem

On MacOS (Big Sur), start two services via dotnet run at the same time (both using services.AddDaprSidekick as a configured service). Last service to start will result in above error. Also, the error appears when running the tests in the dapr-sidekick-dotnet-project on macOS:

Man.Dapr.Sidekick.Process.ProcessCommandLineTests+Constructor.Should_retrieve_commandline

System.EntryPointNotFoundException : OpenProcess assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) Man.Dapr.Sidekick.Native.NativeProcess.OpenProcess(Man.Dapr.Sidekick.Native.NativeProcess/OpenProcessDesiredAccessFlags,bool,uint)
  at Man.Dapr.Sidekick.Native.NativeProcess.GetCommandLine (System.Diagnostics.Process process, System.String& commandLine) [0x00006] in /dapr-sidekick-dotnet/src/Man.Dapr.Sidekick/Native/NativeProcess.cs:89 
  at Man.Dapr.Sidekick.Process.ProcessCommandLine..ctor (Man.Dapr.Sidekick.Process.SystemProcess systemProcess) [0x00000] in /dapr-sidekick-dotnet/src/Man.Dapr.Sidekick/Process/ProcessCommandLine.cs:10 
  at Man.Dapr.Sidekick.Process.ProcessCommandLineTests+Constructor.Should_retrieve_commandline () [0x0000e] in /dapr-sidekick-dotnet/tests/Man.Dapr.Sidekick.Tests/Process/ProcessCommandLineTests.cs:14 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:395 

Release Note

RELEASE NOTE:

Note: I started digging around in the code and it occurred to me that this might actually be the expected behaviour. The problematic code is in NativeProcess.cs and the second line of that file (https://github.com/man-group/dapr-sidekick-dotnet/blob/main/src/Man.Dapr.Sidekick/Native/NativeProcess.cs#L2) mentions a StackOverflow article. I had a look and the NativeProcess.cs implementation is inspired by this project: https://github.com/sonicmouse/ProcCmdLine. In the README of mentioned project, it is said that this implementation is Windows only. It would be great if you would consider Mac/Linux support as Dapr Sidekick is a sorely missed feature that addresses an issue we have had in our team for a long time ❤️

Dapr Actors not working with Dapr Sidekick after changing Sidecar Ports

Expected Behavior

Why does adding an appsettings.json and changing the Sidecar Port of the DemoActor Host stops the correct execution and throws ActorMethodInvocationException?

appsettings.json added

{
  "DaprSidekick": {
    "Enabled": true,
    "Sidecar": {
      "DaprHttpPort": "3501",
      "DaprGrpcPort": "50001",
      "MetricsPort": "9001"
    }
  }
}

Actual Behavior

Actor Client Error

Dapr.Actors.ActorMethodInvocationException
  HResult=0x80131500
  Message=Remote Actor Method Exception
  Source=Dapr.Actors
  StackTrace:
   at Dapr.Actors.DaprHttpInteractor.<InvokeActorMethodWithRemotingAsync>d__10.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Dapr.Actors.Communication.Client.ActorRemotingClient.<InvokeAsync>d__5.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Dapr.Actors.Client.ActorProxy.<InvokeMethodAsync>d__32.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at ActorClient.Program.<Main>d__0.MoveNext() in C:\Repos\dapr-sidekick-dotnet\samples\Actor\ActorSample\ActorSample.ActorClient\Program.cs:line 47

Inner Exception 1:
ActorInvokeException: No connection could be made because the target machine actively refused it.

Steps to Reproduce the Problem

Modified version of the original Sidekick Actor example
Check: fbridger@a746ea0

Local Dapr secrets file not found after 1.0.1-rc.0.6

Expected Behavior

Local dapr secrets file is found and loaded

Actual Behavior

Local dapr secrets file is not found

Steps to Reproduce the Problem

  • Navigate to all -> samples -> AspNetCore -> ConsulSample -> ConsolSample.Sender
  • Create ./dapr/components/localSecretStore.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: azurekeyvault
  namespace: default
spec:
  type: secretstores.local.file
  version: v1
  metadata:
  - name: secretsFile
    value: dapr.secrets.local
  - name: nestedSeparator
    value: ":"
  • Create ./dapr.secrets.local
{
}

Run application and check the logs
image

  • Open ConsulSample.Sender.csproj
  • Change version
  <ItemGroup>
<!--    <ProjectReference Include="..\..\..\..\src\Man.Dapr.Sidekick.AspNetCore\Man.Dapr.Sidekick.AspNetCore.csproj" />-->
    <PackageReference Include="Man.Dapr.Sidekick.AspNetCore" Version="1.0.1-rc.0.6" />
  </ItemGroup>

Start application and see that there are no errors in the debug logs.

Can't find service when hosted in IIS

Expected Behavior

I should be able to invoke a service through the sidecar e.g.

curl http://localhost:3500/v1.0/invoke/myservice/method/api/products

Actual Behavior

After a reboot I get the following response:

{"errorCode":"ERR_DIRECT_INVOKE","message":"failed to invoke, id: myservice, err: couldn't find service: myservice"}

If I kill daprd sidekick restarts it automatically and then the invoke works. Restarting the site, app pool or IIS server does not cause this issue; it only seems to be on reboot.

The dapr-sidecar healthcheck reports healthy.

These are the only warnings in the log. I've not been able to see anything that indicates what's going on.

{"@t":"2024-05-23T15:26:13.9176318+01:00","@l":"Warning","@m":"Error flushing tracing provider: request to http://zipkin:9411/api/v2/spans failed: Post \"http://zipkin:9411/api/v2/spans\": dial tcp: lookup zipkin: no such host","properties":{"SourceContext":"Man.Dapr.Sidekick.DaprSidecarHost","DaprVersion":"1.13.2","DaprAppId":"myservice","DaprInstance":"xxx","DaprScope":"dapr.runtime","DaprTime":"2024-05-23T15:26:13.9171368+01:00","DaprType":"log"}}

{"@t":"2024-05-23T15:26:54.8268335+01:00","@l":"Warning","@m":"mTLS is disabled. Skipping certificate request and tls validation","properties":{"SourceContext":"Man.Dapr.Sidekick.DaprSidecarHost","DaprVersion":"1.13.2","DaprAppId":"myservice","DaprInstance":"xxx","DaprScope":"dapr.runtime.security","DaprTime":"2024-05-23T15:26:54.810182+01:00","DaprType":"log"}}

{"@t":"2024-05-23T15:26:54.8269715+01:00","@l":"Warning","@m":"The default value for 'spec.metric.http.increasedCardinality' will change to 'false' in Dapr 1.14","properties":{"SourceContext":"Man.Dapr.Sidekick.DaprSidecarHost","DaprVersion":"1.13.2","DaprAppId":"myservice","DaprInstance":"xxx","DaprScope":"dapr.runtime","DaprTime":"2024-05-23T15:26:54.8218184+01:00","DaprType":"log"}}

Steps to Reproduce the Problem

I'm publishing the service to IIS where I have set the app pool to be always running and the site to have preload enabled. This means the service is started automatically and the sidecar is also started automatically as expected. I create a localhost binding on the site with a unique port number and use this as the AppPort.

Release Note

RELEASE NOTE:

Support Visual Studio 2022 Preview

Describe the feature

First things first: I love the intent and the design of this integration. Well done!

I spent a few hours trying to get an existing Dapr based actor system to debug in Visual Studio 2022 after playing with the DaprSidekick samples. It didn't occur to me that VS could be the problem because the logs looked identical up to the point where I tried to call one of my actor methods. It failed with an address not found error "ERR_ACTOR_INVOKE_METHOD error invoke actor method: error finding address for actor type MarketActor with id US". The health checks were also not firing which may indicate something is not getting hooked up in the same way as in VS2019.

The services.AddActor calls were executed, apparently successfully. When I tried the same solution in VS2019, I got a number of DI errors during F5 that I did not get in VS2022. Fixing the DI error did not change the behavior in VS2022. This issue reproduces with the Actor sample in your repo, so I didn't provide a link to my own repo.

Release Note

RELEASE NOTE:
DaprSideKick-Actors-VS22-Error.log

Dapr instances started by Sidekick doesn't show in Dashboard

Expected Behavior

Dapr instances launched by Sidekick show show in Dapr Dashboard

Actual Behavior

Dapr Dashboard is not showing any application in the Dapr Applications table

Steps to Reproduce the Problem

  1. Launch a ASP.Net Core Web API with Sidekick enabled.
  2. Start Dapr Dashboard
    dapr dashboard
    
  3. Open Dapr Dashboard in browser http://localhost:8080
  4. Check that Dapr application is not listed

Namespace environment variable not set

Expected Behavior

Namespace environment variable set on daprd process.

Actual Behavior

Namespace variable not set (verified with ProcessExplorer).
DAPR_* variables are set.

Steps to Reproduce the Problem

CLI version: 1.4.0
Runtime version: 1.3.0
Man.Dapr.Sidekick 1.1.0
Windows 10

  • Create component config which points to non-existing IP (see below)
  • Set Namespace in json config to
    • only components from configured namespace should be loaded
  • daprd will try to load component configuration and show connection error despite namespace in sidecar config
    • process component mqtt-pubsub error: init timeout for component mqtt-pubsub exceeded after 5s"

pubsub.yml

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: mqtt-pubsub
namespace: remote
spec:
type: pubsub.mqtt
version: v1
metadata:

  • name: url
    value: "mqtt://192.168.137.1:1883"

appsettings.json
"DaprSidekick": {
"Sidecar": {
"Namespace": "local"
}
}

Release Note

RELEASE NOTE: FIX Missing Namespace environment variable.

Support for ASP.NET (Framework 4.6.x and more) && pub sub

In my company we want to move to Dapr.io but like you we have a lot of .NET 4.6 ASP.NET services.

The example I have seen in your repo is based on a console application and I would like to know if it is supported to run dapr sidekick with a ASP.NET Web Application (.NET Framework) running on IIS?

The next question is also if with your library we can publish to a pub-sub component? This is what I need to integrate the new code with the old one (by using CloudEvents)?
I have forked the current Dapr Client SDK to support .Net Standard 2.0 and 2.1 so we can use it also in legacy app but they have refused this.

Thanks for the support and the good job you did.

Support for Dapr 1.13

Describe the feature

  • Update all the Dapr library components to the latest Dapr 1.13
  • Support additional command-line parameters
  • Fix issues with Sentry and Placement hosting

Why Newtonsoft Json.NET dependency is required?

First of all, I want to say thanks for open sourcing DAPR Sidekick. I am very interested in leveraging it.

One question that I have is related to the Newtonsoft Jason.NET library and understand why this is required. I have used this library a lot in the past but I've found a lot of benchmarks comparing different Json libraries and it seems that it's performance is one the main disadvantages.

Thanks again to all of the MAN Group team members for developing this package.

Empty "SentryAddress" property passes empty "--sentry-address" to daprd

Expected Behavior

Starting Dapr Sidecar with an empty SentryAddress in appsettings.json should not pass an empty string to the daprd command line.

Actual Behavior

With the following entry in appsettings.json:

  "Dapr": {
    "Sidecar": {
      "mTLS": false,
      "SentryAddress": "",
    }
  }  

This should not pass the --sentry-address parameter to the daprd command-line, however it passes the parameter with an empty value:

[08:22:37 INF] Starting Process C:\Users\scjones\.dapr\bin\daprd.exe with arguments '--app-id controllersample --app-port 5000 --dapr-grpc-port 50001 --dapr-http-port 3500 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --sentry-address  --config C:\Users\scjones\.dapr\config.yaml --components-path C:\Users\scjones\.dapr\components'

Steps to Reproduce the Problem

Open the ControllerSample and add the above section to appsettings.json then run the solution, the command-line above will be output in the logs.

Release Note

RELEASE NOTE: FIX Bug where an empty SentryAddress value in appsettings.json would pass an empty parameter to the daprd command line

Can I use sidekick to access secrets?

Ask your question here

Seem to have a catch-22 on this.

For dev, I'd like to use sidekick, but ulltimately in prod the app will run under k8s. In prod, though, the idea is that the app will query secrets to obtain its connection strings etc, and then set up its DB context etc. However, this stuff has to be done before a[[ = builder.Build();

My issue though is that daprd isn't started until after app.Run(), and I can't get my secrets until it is running, but I need my secrets to build the DB context, and yet that needs to be done before builder.Build()

app = builder.Build() < app.Run() < daprd.exe < query for secrets < build connection string < create DB context < app = builder.Build()

Hopefully I'm being very dumb?

Attach mode health check throws exception if daprd exits

Expected Behavior

When running sidekick in attach mode, if the daprd process goes down then the dapr process health check should report unhealthy

Actual Behavior

The dapr process health is throwing an exception if the daprd process is unavailable during attach mode. The sidekick is under the impression that the process is still running and attempts a http request which fails

Steps to Reproduce the Problem

  1. run daprd with an app-id and app-port
  2. start a sidekick service with a matching app-id and app-port
  3. wait for service to attach and report healthy
  4. kill the daprd process
  5. observe HttpRequestException in logs

Release Note

TBD

client.CheckHealthAsync() return false

When execute client.CheckHealthAsync() it return false when running with dapr sidekick
When i run it with dapr run ... it returns true.

Also the same with WaitForSidecarAsync, it works with dapr run, but not with the dapr sidekick.

Any idea why? Is it because daprd is not discovered? The same issue with dashboard that is able to discover dapr services started with daprd?

Sidecar Placement Address should be optional

Expected Behavior

The --placement-host-address parameter should not be passed to the Dapr Sidecar by default unless specifically instructed.

Actual Behavior

As of Dapr 1.2 when the CLI dapr.exe launches daprd.exe it adds a default placement service address:

daprd ... --placement-host-address 127.0.0.1:6050 ...

Normally placement would be running in a local development environment in a container exposing that port (or 50005 on non-Windows) but if a service doesn't need placement/actor support it should be possible to disable this as at present the sidecar continually gives DBG log warnings about being unable to connect:

12:12:16.857 [DBG] [Man.Dapr.Sidekick.DaprSidecarHost]  try to connect to placement service: 127.0.0.1:6050
12:12:16.862 [DBG] [Man.Dapr.Sidekick.DaprSidecarHost]  error connecting to placement service: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: tls: first record does not look like a TLS handshake"

As Sidekick is invoking daprd.exe directly, it would be useful if Sidekick had a configuration option to override this so it could prevent the --placement-host-address being specified entirely, which would result in a single warning-level log message on startup which might be preferable:

time="2021-06-02T12:48:36.2391259+01:00" level=warning msg="failed to init actors: actors: couldn't connect to placement service: address is empty" app_id=dapr-gateway instance=LONL20439 scope=dapr.runtime type=log ver=1.2.0

Note also that setting the existing DaprSidecarOptions.PlacementHostAdress to an empty string does not currently prevent the default address being passed to daprd.exe.

Steps to Reproduce the Problem

  1. Make sure Dapr is fully initialized locally (i.e. dapr init)
  2. Add Dapr Sidekick to a new ASP.NET Core Web API project
  3. Set the default Microsoft log level to Debug
  4. Make sure the default placement service container is not running
  5. Run the project in Console mode - the log messages above will be displayed.

RELEASE NOTE:

FIX: Do not assign a default placement-host-address to Sidecar

Adding secrets as part of ConfigurationBuilder

Expected Behavior

I add configuration from from secrets through ConfigurationBuilder.

var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
.AddDaprSecretStore("secret-store", daprClient)
.Build();

The issue is that these seems to happen before sidekick "kicks" in. So it is unable to find the secrets configuration. Because you add sidekick as part of ConfigureServices. I was able to work around this to setup the configuration as part of the

So what this should do is load all the secrets into the configuration so if you have let's say json configuration like this:
"SimpleConfigTest": {
"ConfigValue": "Not from secrets"
}
And in the secrets you have:
"SimpleConfigTest": {
"SecretValue": "From secrets"
}
And we could have like a SimpleConfigText object that is added to DI with the IOptions pattern.

services.Configure(configuration.GetSection("SimpleConfigTest"));

The biggest point is that this works with Dapr and the objects are initialized and works without sidekick.

To reproduce, create a secret store. I have a local secret store right now for development. Setup configuration to pull from the secret store.

Below is the stack trace seen.. Thanks!

at System.Net.Http.HttpClient.HandleFailure(Exception e, Boolean telemetryStarted, HttpResponseMessage response, CancellationTokenSource cts, CancellationToken cancellationToken, CancellationTokenSource pendingRequestsCts)
at System.Net.Http.HttpClient.<g__Core|83_0>d.MoveNext()
at Dapr.Client.DaprClientGrpc.d__60.MoveNext()
at Dapr.Client.DaprClientGrpc.d__61.MoveNext()
at Dapr.Extensions.Configuration.DaprSecretStore.DaprSecretStoreConfigurationProvider.d__16.MoveNext() in //src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs:line 193
at Dapr.Extensions.Configuration.DaprSecretStore.DaprSecretStoreConfigurationProvider.Load() in /
/src/Dapr.Extensions.Configuration/DaprSecretStoreConfigurationProvider.cs:line 184
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers) in //src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs:line 36
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build() in /
/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs:line 54
at Cmp.Api.Program.CreateWebHostBuilder(String[] args) in C:\projects\nova.api\Nova.Api\Program.cs:line 25
at Cmp.Api.Program.Main(String[] args) in C:\projects\nova.api\Nova.Api\Program.cs:line 14

HTTP Error 400. The request hostname is invalid when invoking api

Expected Behavior

Expect Http 200 and view dapr logs in the VS console

Actual Behavior

HTTP Error 400. The request hostname is invalid when invoking an api thru the sidecar on a ASP.NET Web Api (.NET Framework 4.7.2)

Steps to Reproduce the Problem

Create a new ASP.NET Web Api in Visual Studio 2019
Add Man.Dapr.Sidekick and Man.Dapr.Sidekick.Extensions.Logging Nuget packages
Add dapr setup in Global.asx
Add tests methods in Controllers
Call api: curl http://localhost:3500/v1.0/invoke/dotnetframeworkpublisher/method/api/test

The dapr metrics, health, and status looks good but no dapr logs in the console
Everything works as expected with .Net Core

ServiceInvocationSample - error when using CreateInvokeHttpClient

Fresh install of Dapr 1.5. Opens the all.sln in VS2022 and set ServiceInvocationSample as default.

When hitting the /sidecar an exception happens:

Below are the logs until I hit the endpoint

[13:29:15 INF] Dapr Process Status Change: Stopped -> Initializing
[13:29:15 INF] AppId not specified, assigning default value: serviceinvocationsample
[13:29:15 INF] Dapr expected process name set to daprd
[13:29:15 INF] Now listening on: http://localhost:5000
[13:29:15 INF] Application started. Press Ctrl+C to shut down.
[13:29:15 INF] Hosting environment: Development
[13:29:15 INF] Content root path: C:\Projects\dapr-sidekick-dotnet\samples\AspNetCore\ServiceInvocationSample\ServiceInvocationSample
[13:29:15 INF] Dapr initial directory: C:\Users\lars.erik.finholt\.dapr
[13:29:15 INF] Dapr runtime directory: C:\Users\lars.erik.finholt\.dapr
[13:29:15 INF] Dapr process binary: C:\Users\lars.erik.finholt\.dapr\bin\daprd.exe
[13:29:15 INF] Dapr Process Status Change: Initializing -> Starting
[13:29:15 INF] Environment variable DAPR_GRPC_PORT set to 50001
[13:29:15 INF] Environment variable DAPR_HTTP_PORT set to 3500
[13:29:15 INF] Starting Process C:\Users\lars.erik.finholt\.dapr\bin\daprd.exe with arguments '--app-id serviceinvocationsample --app-port 5000 --dapr-grpc-port 50001 --dapr-http-port 3500 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users\lars.erik.finholt\.dapr\config.yaml --components-path C:\Users\lars.erik.finholt\.dapr\components'
[13:29:15 INF] Process daprd PID:10756 started successfully
[13:29:19 INF] Request starting HTTP/1.1 GET http://localhost:5000/weatherforecast/status
[13:29:20 INF] 2021/11/19 13:29:19 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
[13:29:20 INF] Executing endpoint 'ServiceInvocationSample.Controllers.WeatherForecastController.GetStatus (ServiceInvocationSample)'
[13:29:20 INF] starting Dapr Runtime -- version 1.5.0 -- commit 83fe579f5dc93bef1ce3b464d3167a225a3aff3a
[13:29:20 INF] log level set to: debug
[13:29:20 INF] Route matched with {action = "GetStatus", controller = "WeatherForecast"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.ActionResult GetStatus() on controller ServiceInvocationSample.Controllers.WeatherForecastController (ServiceInvocationSample).
[13:29:20 INF] metrics server started on :9090/
[13:29:20 INF] standalone mode configured
[13:29:20 INF] app id: serviceinvocationsample
[13:29:20 INF] mTLS is disabled. Skipping certificate request and tls validation
[13:29:20 INF] Executing ObjectResult, writing value of type '<>f__AnonymousType0`2[[Man.Dapr.Sidekick.Process.DaprProcessInfo, Man.Dapr.Sidekick, Version=1.0.0.0, Culture=neutral, PublicKeyToken=740d643db1ccf811],[Man.Dapr.Sidekick.DaprSidecarOptions, Man.Dapr.Sidekick, Version=1.0.0.0, Culture=neutral, PublicKeyToken=740d643db1ccf811]]'.
[13:29:21 INF] Executed action ServiceInvocationSample.Controllers.WeatherForecastController.GetStatus (ServiceInvocationSample) in 120.6466ms
[13:29:21 INF] Executed endpoint 'ServiceInvocationSample.Controllers.WeatherForecastController.GetStatus (ServiceInvocationSample)'
[13:29:21 INF] Request finished in 1098.4343ms 200 application/json; charset=utf-8
[13:29:21 INF] local service entry announced: serviceinvocationsample -> 10.99.16.103:51494
[13:29:21 INF] Initialized name resolution to mdns
[13:29:21 INF] loading components
[13:29:21 INF] component loaded. name: pubsub, type: pubsub.redis/v1
[13:29:21 INF] Request starting HTTP/1.1 GET http://127.0.0.1:5000/dapr/config application/json
[13:29:21 INF] waiting for all outstanding components to be processed
[13:29:21 INF] Request finished in 6.6887ms 404
[13:29:21 INF] component loaded. name: statestore, type: state.redis/v1
[13:29:21 INF] all outstanding components processed
[13:29:21 INF] enabled gRPC tracing middleware
[13:29:21 INF] Request starting HTTP/1.1 GET http://127.0.0.1:5000/dapr/subscribe application/json
[13:29:21 INF] enabled gRPC metrics middleware
[13:29:21 INF] Request finished in 3.5232ms 404
[13:29:21 INF] API gRPC server is running on port 50001
[13:29:21 INF] enabled metrics http middleware
[13:29:21 INF] enabled tracing http middleware
[13:29:21 INF] http server is running on port 3500
[13:29:21 INF] The request body size parameter is: 4
[13:29:22 INF] enabled gRPC tracing middleware
[13:29:22 INF] enabled gRPC metrics middleware
[13:29:22 INF] internal gRPC server is running on port 51494
[13:29:22 INF] application protocol: http. waiting on port 5000.  This will block until the app is listening on that port.
[13:29:22 INF] application discovered on port 5000
[13:29:22 INF] application configuration loaded
[13:29:22 INF] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s
[13:29:22 INF] placement tables updated, version: 0
[13:29:22 INF] dapr initialized. Status: Running. Init Elapsed 1221.5228ms
[13:29:22 INF] Dapr Process Status Change: Starting -> Started
[13:29:22 INF] Caching successful startup options for future restart attempts
[13:29:26 INF] Request starting HTTP/1.1 GET http://localhost:5000/weatherforecast/sidecar
[13:29:26 INF] Executing endpoint 'ServiceInvocationSample.Controllers.WeatherForecastController.GetViaSidecar (ServiceInvocationSample)'
[13:29:26 INF] Route matched with {action = "GetViaSidecar", controller = "WeatherForecast"}. Executing controller action with signature System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[ServiceInvocationSample.WeatherForecast]] GetViaSidecar() on controller ServiceInvocationSample.Controllers.WeatherForecastController (ServiceInvocationSample).
[13:29:30 INF] Executed action ServiceInvocationSample.Controllers.WeatherForecastController.GetViaSidecar (ServiceInvocationSample) in 3999.3558ms
[13:29:30 INF] Executed endpoint 'ServiceInvocationSample.Controllers.WeatherForecastController.GetViaSidecar (ServiceInvocationSample)'
[13:29:30 ERR] An unhandled exception has occurred while executing the request.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
   at ServiceInvocationSample.Controllers.WeatherForecastController.GetViaSidecar() in C:\Projects\dapr-sidekick-dotnet\samples\AspNetCore\ServiceInvocationSample\ServiceInvocationSample\Controllers\WeatherForecastController.cs:line 70
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
[13:29:30 INF] Request finished in 4312.0357ms 500 text/html; charset=utf-8
[13:29:30 INF] Request starting HTTP/1.1 GET http://localhost:5000/_framework/aspnetcore-browser-refresh.js
[13:29:30 INF] Request finished in 72.8869ms 200 application/javascript; charset=utf-8
[13:31:46 INF] Request starting HTTP/1.1 GET http://localhost:5000/weatherforecast/sidecar
[13:31:46 INF] Executing endpoint 'ServiceInvocationSample.Controllers.WeatherForecastController.GetViaSidecar (ServiceInvocationSample)'
[13:31:46 INF] Route matched with {action = "GetViaSidecar", controller = "WeatherForecast"}. Executing controller action with signature System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[ServiceInvocationSample.WeatherForecast]] GetViaSidecar() on controller ServiceInvocationSample.Controllers.WeatherForecastController (ServiceInvocationSample).

My first attempt with a ServiceA project calling a ServiceB project failed with the same error, that's why I tried the sample, and got the same result.

Any idea what I've done wrong?

IDaprSidecarHttpClientFactory.CreateInvokeHttpClient created HttpClient throws exception

Expected Behavior

Perform service invocation via HTTP client created via IDaprSidecarHttpClientFactory.CreateInvokeHttpClient(appid);

Actual Behavior

System.NullReferenceException: Object reference not set to an instance of an object.
at Man.Dapr.Sidekick.Http.HttpContextInvocationHandler.OnAfterSendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Man.Dapr.Sidekick.DaprClient.InvocationHandler.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

Steps to Reproduce the Problem

Dapr 1.4
sidekick 1.2

                var daprClient = componentRegistration.ComponentHost.Services
                        .GetRequiredService<IDaprSidecarHttpClientFactory>();
                var appid = componentRegistration.DaprSidecarHost.GetProcessOptions().AppId;
                Debug.Assert(!string.IsNullOrEmpty(appid));
                using var http = daprClient.CreateInvokeHttpClient(appid);
                Debug.Assert(http != null);
                // 🧨🧨🧨
                var result = await http.GetAsync("testMethod");

Release Note

RELEASE NOTE:
FIX Bug in IDaprSidecarHttpClientFactory.CreateInvokeHttpClient

Dose dapr-sidekick Support dotnet apps deployed in IIS

Ask your question here

We have several aspnet core 6 web apps deployed in windows server 2016 IIS, and the network is on-promised. can not use Docker.
We always want to use Dapr to make some microservice, The biggest problem is the process daemon . If the server shutdown or restart, out app should be auto restarted, so we choose IIS In Process Mode to publish our sites, because there are a bunches of toolchains like MSDeloy, VisualStudio, Rider, AzureDevops to support.
But IIS can not start daprd process for app side car, if we use the default self-hosted mode, can not auto restart app or dapr side car , or directed start app as backgroud service, not to stuck with the console.

This project seems to solve out problem, but I found it can not properly start daprd when I pub the website to iis.
image

Slight delay after starting sidecar

I noticed when using sidekick to start the sidecar from an integration test the sidecar was not immediately able to handle requests. This was resolved by introducing a slight delay of ~200ms.

When trying to implement a solution for this I noticed that there's a synchronous API while there's a lot of asynchrony involved.

I have a PR ready to show how I'm trying to use your library and where it doesn't fit that purpose right now.

Support environment variables for Dapr Sidekick settings

Describe the feature

It should be possible to use environment variables to configure some/all of the Dapr Sidekick settings such that any environment variable prefixed with DAPRSIDEKICK_ (say) could be read on startup and mapped to configuration values.

As an example, it may be desirable to disable Dapr Sidekick entirely in a container deployed scenario, such that Sidekick is used for a seamless development and debugging experience in Visual Studio but on deployment is disabled in containers. This can currently be achieved by modifying the appsettings.json to set the top-level Enabled setting to false:

{
  "Dapr": {
    "Enabled": false
  }
 }

However some orchestration platforms (or docker compose) might prefer to set an environment variable such as DAPRSIDEKICK_ENABLED=false to achieve the same thing.

ERR - app returned http status code 400 from subscription endpoint

Expected Behavior

I am having a very weird behaviour when I I debug the ASP.Net Core application from Visual Studio 2019.

The ASP.NET Core application is not being subscribed to any of the Events due to what I believe is a timing problem.

However, if I run the application using dotnet run everything works correctly.

Is this something related to SideKick? the dotnet-sdk? or Dapr Sidecar?

Actual Behavior

The application is not receiving events when it's being Debug from Visual Studio

FAILURE

Logs in DEBUG mode from Visual Studio 2019 (see ERR line)

ERR - app returned http status code 400 from subscription endpoint {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", DaprVersion="1.3.0", DaprAppId="notifications-api", DaprInstance="MYMACHINE", DaprScope="dapr.runtime", DaprTime="2021-08-25T12:53:40.0125323-03:00", DaprType="log", from="notification-service", ThreadId=15, Version="1.0.0.0", ContainerId="MYMACHINE"}
DBG - app responded with subscriptions [] {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", DaprVersion="1.3.0", DaprAppId="notifications-api", DaprInstance="MYMACHINE", DaprScope="dapr.runtime", DaprTime="2021-08-25T12:53:40.0125323-03:00", DaprType="log", from="notification-service", ThreadId=15, Version="1.0.0.0", ContainerId="MYMACHINE"}
INF - dapr initialized. Status: Running. Init Elapsed 187.43099999999998ms {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", DaprVersion="1.3.0", DaprAppId="notifications-api", DaprInstance="MYMACHINE", DaprScope="dapr.runtime", DaprTime="2021-08-25T12:53:40.0345807-03:00", DaprType="log", from="notification-service", ThreadId=15, Version="1.0.0.0", ContainerId="MYMACHINE"}
INF - Dapr Process Status Change: Starting -> Started {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", from="notification-service", ThreadId=15, Version="1.0.0.0", ContainerId="MYMACHINE"}

SUCCEED

Logs when using DOTNET RUN mode

DBG - app responded with subscriptions [{acme-broker activationcode-for-selfregistered-user Notification/Email/UserRegistrationEmail map[] []} {acme-broker activationcode-for-new-user-added-as-contact Notification/Email/ContactRequireActivationAssociation map[] []} {acme-broker existing-user-added-as-contact Notification/Email/ContactAssociation map[] []} {acme-broker activationcode-for-new-user-added Notification/Email/UserRequireActivationAssociation map[] []} {acme-broker existing-user-associated Notification/Email/UserAssociation map[] []}] {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", DaprVersion="1.3.0", DaprAppId="notifications-api", DaprInstance="MYMACHINE", DaprScope="dapr.runtime", DaprTime="2021-08-25T12:58:58.623539-03:00", DaprType="log", from="notification-service", ThreadId=4, Version="1.0.0.0", ContainerId="MYMACHINE"}
INF - app is subscribed to the following topics: [activationcode-for-selfregistered-user activationcode-for-new-user-added-as-contact existing-user-added-as-contact activationcode-for-new-user-added existing-user-associated] through pubsub=acme-broker {SourceContext="Man.Dapr.Sidekick.DaprSidecarHost", DaprVersion="1.3.0", DaprAppId="notifications-api", DaprInstance="MYMACHINE", DaprScope="dapr.runtime", DaprTime="2021-08-25T12:58:58.6267787-03:00", DaprType="log", from="notification-service", ThreadId=4, Version="1.0.0.0", ContainerId="MYMACHINE"}

Steps to Reproduce the Problem

Run the application from Visual Studio 2019 in DEBUG mode, launch dapr sidecar using Dapr Sidekick

Use dapr sidekick with an integration test

I try to use the dapr sidekick with an integration test (Using Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory).

I can see in the output log:

Dapr Process Status Change: Stopped -> Initializing
Host application is initializing, waiting to start Dapr process...
Host application ready, starting Dapr process
Stopping Process "daprd" PID:null
Dapr Process Status Change: Initializing -> Stopping
Dapr Process Status Change: Stopping -> Stopped
Dapr Process Status Change: Stopped -> Initializing
Dapr expected process name set to "daprd"
Dapr initial directory: "C:\Users\[myname]\.dapr"
Dapr runtime directory: "C:\Users\[myname]\.dapr"
Dapr process binary: "C:\Users\[myname]\.dapr\bin\daprd.exe"
Dapr Process Status Change: Initializing -> Starting
Environment variable "DAPR_GRPC_PORT" set to 50002
Environment variable "DAPR_HTTP_PORT" set to 3501
Starting Process "C:\Users\[myname]\.dapr\bin\daprd.exe" with arguments '"--app-id jp-core --app-port 8500 --dapr-grpc-port 50002 --dapr-http-port 3501 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users\[myname]\.dapr\config.yaml --components-path C:\Users\[myname]\.dapr\components"'

I also wait for IDaprSidecarHost.CheckHealthAsync() to be true

What I noted while debugging is the the dapr http port from the daprclient is set to 3500, and not 3501 as logged above.

Any idea how I achieve this?


Note: when i start my api, the sidecar it is started fine:

[18:13:31 INF] Dapr Process Status Change: Stopped -> Initializing

[18:13:31 INF] Host application is initializing, waiting to start Dapr process...
[18:13:31 INF] Host application ready, starting Dapr process
[18:13:32 INF] AppId not specified, assigning default value: core-api
[18:13:32 INF] Dapr expected process name set to daprd
[18:13:32 INF] Dapr initial directory: C:\Users[myname].dapr
[18:13:32 INF] Dapr runtime directory: C:\Users[myname].dapr
[18:13:32 INF] Dapr process binary: C:\Users[myname].dapr\bin\daprd.exe
[18:13:32 INF] Dapr Process Status Change: Initializing -> Starting
[18:13:32 INF] Environment variable DAPR_GRPC_PORT set to 50002
[18:13:32 INF] Environment variable DAPR_HTTP_PORT set to 3501
[18:13:32 INF] Starting Process C:\Users[myname].dapr\bin\daprd.exe with arguments '--app-id core-api --app-port 5088 --dapr-grpc-port 50002 --dapr-http-port 3501 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users[myname].dapr\config.yaml --components-path C:\Users[myname].dapr\components'
[18:13:32 INF] Process daprd PID:48396 started successfully
[18:13:33 INF] starting Dapr Runtime -- version 1.10.2 -- commit d02fb79c051f8d7d45097d5eb06b3153ce4a3a24
[18:13:33 INF] log level set to: debug
[18:13:33 INF] metrics server started on :9090/
[18:13:33 INF] Resiliency configuration loaded.
[18:13:33 INF] standalone mode configured

Great project

Thank you for all your hard work and great community video.

Really enjoyed the presentation.

reserving port for AppPort?

I love the auto port assignment stuff.

Is there a way to get that working with the actual port the app is listening on?

The log output below shows the AppPort is a preferred port, coming from launchSettings.json.
But even when I remove applicationUrl from launchSettings.json, it still logs out "preferred port"?

[14:10:24 DBG] Assigning preferred port 5020 for option AppPort
[14:10:24 DBG] Reserving new port 50001 for option DaprGrpcPort
[14:10:24 DBG] Reserving new port 3500 for option DaprHttpPort
[14:10:24 DBG] Reserving new port 9090 for option MetricsPort
[14:10:24 DBG] Reserving new port 7777 for option ProfilePort

Allow custom CLI flags to be passed

Describe the feature

I recently found that a CLI flag --dapr-listen-addresses is not supported by dapr sidekick. I think it would be useful to allow custom flags to be specified to work around delays in implementing configuration options. Maybe options.Sidekick.AdditionalArguments?

I logged the specific --dapr-listen-addresses issue as #55.

Release Note

RELEASE NOTE:

Invoking Actor methods from .Net Framework

I am using the WCF Sample project as base to enable DAPR in a .NET Framework app. I was wondering if it's possible to invoke Actor methods running in other DAPR services from a .NET Framework service. I see example of calling Service methods using HTTP Client created using HttpClientFactory but I am not sure how to call an Actor method. I can't use the official Dapr.Actor package as it relies on .NET Core

Dapr Service not found.

Service not found when using SideKick!

Added Sidekick

			services.AddDaprSidekick(Configuration, c =>
			{
				c.Sidecar = new Man.Dapr.Sidekick.DaprSidecarOptions
				{
					AppId = "BoostQuestPipeline"
				};
			});

Ran application.

Actual Behavior

Service does not appear in Dapr Dashboard.

The following command fails to find service:

dapr invoke --app-id BoostQuestPipeline --method OnBoostJoined --data-file sample.json

Error message from command:
error invoking app BoostQuestPipeline: app ID BoostQuestPipeline not found

Logs

Starting IIS Express ...
Successfully registered URL "http://localhost:2417/" for site "LW.Gamification.BoostQuestPipeline" application "/"
Registration completed for site "LW.Gamification.BoostQuestPipeline"
IIS Express is running.
[14:41:52 INF] Starting web host
[14:41:53 INF] Dapr Process Status Change: Stopped -> Initializing
[14:41:53 INF] Dapr expected process name set to daprd
[14:41:53 INF] Dapr initial directory: C:\Users\David.dapr
[14:41:53 INF] Dapr runtime directory: C:\Users\David.dapr
[14:41:53 INF] Dapr process binary: C:\Users\David.dapr\bin\daprd.exe
[14:41:53 INF] Dapr Process Status Change: Initializing -> Starting
[14:41:53 INF] Environment variable DAPR_GRPC_PORT set to 50004
[14:41:53 INF] Environment variable DAPR_HTTP_PORT set to 3500
[14:41:53 INF] Starting Process C:\Users\David.dapr\bin\daprd.exe with arguments '--app-id BoostQuestPipeline --app-port 2417 --dapr-grpc-port 50004 --dapr-http-port 3500 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users\David.dapr\config.yaml --components-path C:\Users\David.dapr\components'
[14:41:53 INF] Process daprd PID:45480 started successfully
[14:41:54 INF] starting Dapr Runtime -- version 1.4.3 -- commit a8ee30180e1183e2a2e4d00c283448af6d73d0d0
[14:41:54 INF] log level set to: debug
[14:41:54 INF] metrics server started on :9090/
[14:41:54 INF] standalone mode configured
[14:41:54 INF] app id: BoostQuestPipeline
[14:41:54 INF] mTLS is disabled. Skipping certificate request and tls validation
[14:41:54 INF] local service entry announced: BoostQuestPipeline -> 192.168.1.12:1779
[14:41:54 INF] Initialized name resolution to mdns
[14:41:55 INF] loading components
[14:41:55 INF] component loaded. name: redis-pubsub, type: pubsub.redis/v1
[14:41:55 INF] waiting for all outstanding components to be processed
[14:41:55 INF] component loaded. name: redis-statestore, type: state.redis/v1
[14:41:55 INF] all outstanding components processed
[14:41:55 INF] enabled gRPC tracing middleware
[14:41:55 INF] enabled gRPC metrics middleware
[14:41:55 INF] API gRPC server is running on port 50004
[14:41:55 INF] enabled metrics http middleware
[14:41:55 INF] enabled tracing http middleware
[14:41:55 INF] http server is running on port 3500
[14:41:55 INF] The request body size parameter is: 4
[14:41:55 INF] enabled gRPC tracing middleware
[14:41:55 INF] enabled gRPC metrics middleware
[14:41:55 INF] internal gRPC server is running on port 1779
[14:41:55 INF] application protocol: http. waiting on port 2417. This will block until the app is listening on that port.
[14:41:55 INF] application discovered on port 2417
[14:41:55 INF] application configuration loaded
[14:41:55 INF] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s
[14:41:55 ERR] app returned http status code 400 from subscription endpoint
[14:41:55 INF] dapr initialized. Status: Running. Init Elapsed 53.607299999999995ms
[14:41:55 INF] Dapr Process Status Change: Starting -> Started
[14:41:55 INF] Caching successful startup options for future restart attempts
[14:41:55 INF] placement tables updated, version: 0

Sidekick in Console apps

This might be easier than I think, but is it possible to use Sidekick in a console app? I have a simulated message sender that I'm using for testing and Sidekick would make this much easier. I did look through the docs, but didn't find anything. I'll try to read through the code as well, but I wanted to save some time by asking here.

If this is not a currently supported scenario, it might be one that's worth looking at for the future.

Are there an extension methods like GetStateAsync<T> ?

The original / official Dapr .NET SDK has support for getting a state key like:

var counter = await daprClient.GetStateAsync<int>(StoreName, Key);

Is there also something defined in this project?


Currently I'm using this code to get a state value:

var counterAsString = await sidekick
            .HttpClientFactory
            .CreateDaprHttpClient().GetStringAsync($"http://localhost:3500/v1.0/state/{StoreName}/{key}");
var counter = int.TryParse(counterAsString, out var c) ? c: 0;
logger.Log(DaprLogLevel.Information, "counter = {0}", counter);

Delay Sidecar Startup until Host Application Started

Expected Behavior

Under ASP.NET Core Sidekick should be launched only when the Host Application is fully started, i.e. when the Kestrel port is opened and the full middleware pipeline is initialized.

Actual Behavior

Sidekick currently starts Dapr Sidecar asynchronously using an IHostedService, which means it is started before the ASP.NET GenericWebHostService hosted service is started to initialize the middleware pipeline and open the host port. This means any environment variables or initialization properties set during the middleware construction may not be passed to the Dapr Sidecar, resulting in potentially missing metadata entries in Consul or anywhere else that relies on environment variables in the yaml files.

We should instead wait until IHostApplicationLifetime.ApplicationStarted signals the application has started before starting the Sidecar process.

Steps to Reproduce the Problem

N/A

Release Note

RELEASE NOTE: FIX Delay Sidecar Startup until Host Application Started

Secret store local file, relative file pathing

In the Dapr Secret store local file examples they tend to use relative file paths to the secrets file, which doesn't seem to work when using SideKick. I keep getting a fatal error , can't find secrets file.

I suspect the fix for this would be to make the working directory for the application consuming the yaml files based on the application you are building rather than the Dapr infrastructure directories.

Any suggestions?

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.