Skip to content

Commit 2738376

Browse files
committed
Add Preliminary Grpc Sample
1 parent 3cff4ce commit 2738376

File tree

19 files changed

+633
-2
lines changed

19 files changed

+633
-2
lines changed

PactNet.sln

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
3737
EndProject
3838
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PactNet.Output.Xunit", "src\PactNet.Output.Xunit\PactNet.Output.Xunit.csproj", "{02E265A1-A7A2-4106-8F6A-5027FDC3FC50}"
3939
EndProject
40+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Grpc", "Grpc", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
41+
EndProject
42+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcGreeter", "samples\Grpc\GrpcGreeter\GrpcGreeter.csproj", "{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}"
43+
EndProject
44+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcGreeterClient", "samples\Grpc\GrpcGreeterClient\GrpcGreeterClient.csproj", "{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}"
45+
EndProject
46+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcGreeterClient.Tests", "samples\Grpc\GrpcGreeterClient.Tests\GrpcGreeterClient.Tests.csproj", "{13756BC3-0750-E2AF-E1F0-565855A3E636}"
47+
EndProject
48+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcGreeter.Tests", "samples\Grpc\GrpcGreeter.Tests\GrpcGreeter.Tests.csproj", "{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}"
49+
EndProject
4050
Global
4151
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4252
Debug|Any CPU = Debug|Any CPU
@@ -155,6 +165,54 @@ Global
155165
{02E265A1-A7A2-4106-8F6A-5027FDC3FC50}.Release|x64.Build.0 = Release|Any CPU
156166
{02E265A1-A7A2-4106-8F6A-5027FDC3FC50}.Release|x86.ActiveCfg = Release|Any CPU
157167
{02E265A1-A7A2-4106-8F6A-5027FDC3FC50}.Release|x86.Build.0 = Release|Any CPU
168+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
169+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|Any CPU.Build.0 = Debug|Any CPU
170+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|x64.ActiveCfg = Debug|Any CPU
171+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|x64.Build.0 = Debug|Any CPU
172+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|x86.ActiveCfg = Debug|Any CPU
173+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Debug|x86.Build.0 = Debug|Any CPU
174+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|Any CPU.ActiveCfg = Release|Any CPU
175+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|Any CPU.Build.0 = Release|Any CPU
176+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|x64.ActiveCfg = Release|Any CPU
177+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|x64.Build.0 = Release|Any CPU
178+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|x86.ActiveCfg = Release|Any CPU
179+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69}.Release|x86.Build.0 = Release|Any CPU
180+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
181+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
182+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|x64.ActiveCfg = Debug|Any CPU
183+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|x64.Build.0 = Debug|Any CPU
184+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|x86.ActiveCfg = Debug|Any CPU
185+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Debug|x86.Build.0 = Debug|Any CPU
186+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
187+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|Any CPU.Build.0 = Release|Any CPU
188+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|x64.ActiveCfg = Release|Any CPU
189+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|x64.Build.0 = Release|Any CPU
190+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|x86.ActiveCfg = Release|Any CPU
191+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A}.Release|x86.Build.0 = Release|Any CPU
192+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
193+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|Any CPU.Build.0 = Debug|Any CPU
194+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|x64.ActiveCfg = Debug|Any CPU
195+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|x64.Build.0 = Debug|Any CPU
196+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|x86.ActiveCfg = Debug|Any CPU
197+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Debug|x86.Build.0 = Debug|Any CPU
198+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|Any CPU.ActiveCfg = Release|Any CPU
199+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|Any CPU.Build.0 = Release|Any CPU
200+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|x64.ActiveCfg = Release|Any CPU
201+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|x64.Build.0 = Release|Any CPU
202+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|x86.ActiveCfg = Release|Any CPU
203+
{13756BC3-0750-E2AF-E1F0-565855A3E636}.Release|x86.Build.0 = Release|Any CPU
204+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
205+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
206+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|x64.ActiveCfg = Debug|Any CPU
207+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|x64.Build.0 = Debug|Any CPU
208+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|x86.ActiveCfg = Debug|Any CPU
209+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Debug|x86.Build.0 = Debug|Any CPU
210+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
211+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|Any CPU.Build.0 = Release|Any CPU
212+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|x64.ActiveCfg = Release|Any CPU
213+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|x64.Build.0 = Release|Any CPU
214+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|x86.ActiveCfg = Release|Any CPU
215+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6}.Release|x86.Build.0 = Release|Any CPU
158216
EndGlobalSection
159217
GlobalSection(SolutionProperties) = preSolution
160218
HideSolutionNode = FALSE
@@ -170,6 +228,11 @@ Global
170228
{5E915D66-917B-4730-B31A-C9727C196346} = {6663C12E-9912-40D0-9310-D119D1F6B023}
171229
{D8B75E48-6E45-468B-8049-B73823C14CB8} = {6663C12E-9912-40D0-9310-D119D1F6B023}
172230
{02E265A1-A7A2-4106-8F6A-5027FDC3FC50} = {CF67D7A1-AE96-420B-9971-65E535B903E8}
231+
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {547DB478-460A-428F-9371-1D653CE85DB5}
232+
{529F37CB-CDA0-6553-EAC9-8DAC2195ED69} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
233+
{917DAC61-55B4-D721-B1ED-B0E352E4CF1A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
234+
{13756BC3-0750-E2AF-E1F0-565855A3E636} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
235+
{DC5371A0-7DE2-4CC5-D0E1-1DF6CB567FA6} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
173236
EndGlobalSection
174237
GlobalSection(ExtensibilityGlobals) = postSolution
175238
SolutionGuid = {C2CBC30C-92D4-4E3A-A5B8-1E5D4E938DFC}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<IsPackable>false</IsPackable>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<PackageReference Include="FluentAssertions" Version="6.12.0" />
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
9+
<PackageReference Include="xunit" Version="2.6.6" />
10+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
14+
</ItemGroup>
15+
<ItemGroup>
16+
<ProjectReference Include="..\..\..\src\PactNet\PactNet.csproj" />
17+
<ProjectReference Include="..\GrpcGreeter\GrpcGreeter.csproj" />
18+
</ItemGroup>
19+
<ItemGroup>
20+
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
21+
</ItemGroup>
22+
</Project>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System.Threading.Tasks;
2+
using System.Threading;
3+
using FluentAssertions;
4+
using Xunit;
5+
using PactNet.Interop;
6+
7+
namespace GrpcGreeter.Tests
8+
{
9+
public class GrpcGreeterTests
10+
{
11+
12+
[Fact]
13+
public void ReturnsVerificationFailureWhenNoRunningProvider()
14+
{
15+
16+
_ = NativeInterop.LogToStdOut(3);
17+
18+
var verifier = NativeInterop.VerifierNewForApplication("pact-dotnet","0.0.0");
19+
NativeInterop.VerifierSetProviderInfo(verifier,"grpc-greeter",null,null,0,null);
20+
NativeInterop.AddProviderTransport(verifier, "grpc",5060,"/","http");
21+
NativeInterop.VerifierAddFileSource(verifier,"../../../../pacts/grpc-greeter-client-grpc-greeter.json");
22+
var VerifierExecuteResult = NativeInterop.VerifierExecute(verifier);
23+
VerifierExecuteResult.Should().Be(1);
24+
}
25+
[Fact]
26+
public async Task ReturnsVerificationSuccessRunningProviderAsync()
27+
{
28+
_ = NativeInterop.LogToStdOut(3);
29+
30+
var verifier = NativeInterop.VerifierNewForApplication("pact-dotnet", "0.0.0");
31+
NativeInterop.VerifierSetProviderInfo(verifier, "grpc-greeter", null, null, 0, null);
32+
NativeInterop.AddProviderTransport(verifier, "grpc", 5000, "/", "https");
33+
NativeInterop.VerifierAddFileSource(verifier, "../../../../pacts/grpc-greeter-client-grpc-greeter.json");
34+
35+
// Arrange
36+
// Setup our app to run before our verifier executes
37+
// Setup a cancellation token so we can shutdown the app after
38+
var cts = new CancellationTokenSource();
39+
var token = cts.Token;
40+
var runAppTask = Task.Run(async () =>
41+
{
42+
await GrpcGreeterService.RunApp([], token);
43+
}, token);
44+
await Task.Delay(2000);
45+
46+
// Act
47+
var VerifierExecuteResult = NativeInterop.VerifierExecute(verifier);
48+
VerifierExecuteResult.Should().Be(0);
49+
NativeInterop.VerifierShutdown(verifier);
50+
// After test execution, signal the task to terminate
51+
cts.Cancel();
52+
}
53+
}
54+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Grpc.AspNetCore" Version="2.71.0" />
15+
<PackageReference Include="Grpc.AspNetCore.Server.Reflection" Version="2.71.0" />
16+
</ItemGroup>
17+
18+
</Project>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using GrpcGreeter.Services;
2+
3+
public class GrpcGreeterService
4+
{
5+
public static async Task Main(string[] args)
6+
{
7+
await RunApp(args, CancellationToken.None);
8+
}
9+
10+
public static async Task RunApp(string[] args, CancellationToken cancellationToken)
11+
{
12+
var builder = WebApplication.CreateBuilder(args);
13+
14+
// Add services to the container.
15+
builder.Services.AddGrpc();
16+
builder.Services.AddGrpcReflection();
17+
18+
19+
var app = builder.Build();
20+
21+
// Configure the HTTP request pipeline.
22+
app.MapGrpcService<GreeterService>();
23+
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
24+
app.MapGrpcReflectionService();
25+
26+
var cancellationTokenSource = new CancellationTokenSource();
27+
var periodicCancellationTask = PeriodicallyCheckCancellation(cancellationToken, cancellationTokenSource);
28+
29+
await app.RunAsync();
30+
31+
cancellationTokenSource.Cancel();
32+
await periodicCancellationTask;
33+
}
34+
35+
private static async Task PeriodicallyCheckCancellation(CancellationToken cancellationToken, CancellationTokenSource periodicCancellationToken)
36+
{
37+
while (!cancellationToken.IsCancellationRequested)
38+
{
39+
if (periodicCancellationToken.Token.IsCancellationRequested)
40+
{
41+
periodicCancellationToken.Cancel();
42+
break;
43+
}
44+
45+
await Task.Delay(1000); // Check for cancellation every second
46+
}
47+
}
48+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": false,
8+
"applicationUrl": "http://localhost:5251",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development"
11+
}
12+
},
13+
"https": {
14+
"commandName": "Project",
15+
"dotnetRunMessages": true,
16+
"launchBrowser": false,
17+
"applicationUrl": "https://localhost:7272;http://localhost:5251",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
}
22+
}
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
syntax = "proto3";
2+
3+
option csharp_namespace = "GrpcGreeter";
4+
5+
package greet;
6+
7+
// The greeting service definition.
8+
service Greeter {
9+
// Sends a greeting
10+
rpc SayHello (HelloRequest) returns (HelloReply);
11+
}
12+
13+
// The request message containing the user's name.
14+
message HelloRequest {
15+
string name = 1;
16+
}
17+
18+
// The response message containing the greetings.
19+
message HelloReply {
20+
string message = 1;
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Grpc.Core;
2+
using GrpcGreeter;
3+
4+
namespace GrpcGreeter.Services
5+
{
6+
public class GreeterService : Greeter.GreeterBase
7+
{
8+
private readonly ILogger<GreeterService> _logger;
9+
public GreeterService(ILogger<GreeterService> logger)
10+
{
11+
_logger = logger;
12+
}
13+
14+
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
15+
{
16+
return Task.FromResult(new HelloReply
17+
{
18+
Message = "Hello " + request.Name
19+
});
20+
}
21+
}
22+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*",
9+
"Kestrel": {
10+
"EndpointDefaults": {
11+
"Protocols": "Http2"
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)