From e97698eddb312829eee1c6914d49f10e93d66c22 Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Thu, 4 Mar 2021 00:49:26 -0500 Subject: [PATCH 01/10] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e230517 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# aurora-cradle-sharp + From 00ab0323c754c1e106ef31eb6eaa7100fee806ad Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Thu, 4 Mar 2021 01:57:21 -0500 Subject: [PATCH 02/10] Initial Commit --- .gitignore | 37 ++++++++++ Src/Program.cs | 27 +++++++ Src/Protos/signal.proto | 130 ++++++++++++++++++++++++++++++++++ Src/Services/SignalService.cs | 19 +++++ Src/Startup.cs | 43 +++++++++++ appsettings.Development.json | 10 +++ appsettings.json | 15 ++++ aurora-cradle-sharp.csproj | 15 ++++ workspace.code-workspace | 12 ++++ 9 files changed, 308 insertions(+) create mode 100644 .gitignore create mode 100644 Src/Program.cs create mode 100644 Src/Protos/signal.proto create mode 100644 Src/Services/SignalService.cs create mode 100644 Src/Startup.cs create mode 100644 appsettings.Development.json create mode 100644 appsettings.json create mode 100644 aurora-cradle-sharp.csproj create mode 100644 workspace.code-workspace diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0626272 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode + +# Rider +.idea + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn + +# Visual Studio 2015 +.vs/ \ No newline at end of file diff --git a/Src/Program.cs b/Src/Program.cs new file mode 100644 index 0000000..e35ec24 --- /dev/null +++ b/Src/Program.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace aurora_cradle_sharp +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + // Additional configuration is required to successfully run gRPC on macOS. + // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/Src/Protos/signal.proto b/Src/Protos/signal.proto new file mode 100644 index 0000000..8ba2d23 --- /dev/null +++ b/Src/Protos/signal.proto @@ -0,0 +1,130 @@ +syntax = "proto3"; + +option csharp_namespace = "aurora_cradle_sharp"; + +package signal; + + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/empty.proto"; + +service Signal{ + //************** + //Party Resource + //************** + //Get Party + rpc ListParties(ListPartiesRequest) returns (ListPartiesResponse); + rpc GetParty(GetPartyRequest) returns (Party); + rpc UpdateParty(UpdatePartyRequest) returns (Party); + rpc CreateParty(CreatePartyRequest) returns (Party); + rpc DeleteParty(DeletePartyRequest) returns (google.protobuf.Empty); + //*************************** + //EventSubscriptions Resource + //*************************** + //List + rpc ListEventSubscriptions(ListEventSubscriptionsRequest) returns (ListEventSubscriptionsResponse); + //Create + rpc SubscribeToEvent(EventSubscriptionRequest) returns (EventSubscription); + + //Delete + rpc DeleteEventSubscription(DeleteEventSubscriptionRequest) returns (google.protobuf.Empty); + //CUSTOM: Create EventSubscription List + rpc SubscribeToEvents(EventSubscriptionListRequest) returns (EventSubscriptionListResponse); + //CUSTOM: Delete all + rpc DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest) returns (google.protobuf.Empty); + + //***** + //Event + //***** + //Get + rpc GetEventStream(GetEventsRequest) returns (stream BaseEvent) {}; +} +message Party { + //The resource name of the party + string name = 1; + string party_id = 2; + string display_name = 3; + string description = 4; + string host_ip = 5; + google.protobuf.Timestamp created_on = 6; +} +message PartyListItem { + string name = 1; + string party_id = 2; +} +message ListPartiesRequest { + int32 page_size = 1; + string page_token = 2; +} +message ListPartiesResponse { + repeated PartyListItem parties = 1; + string next_page_token = 2; +} +message GetPartyRequest { + string party_id = 1; +} +message CreatePartyRequest { + string party_id = 1; + Party party = 2; +} +message DeletePartyRequest { + string party_id = 1; +} +message UpdatePartyRequest { + Party party = 1; + google.protobuf.FieldMask update_mask = 2; +} +/* Event Types */ +enum EventType { + NewPartiesAvailable = 0; +} +message NewPartiesAvailableEvent { +} +message BaseEvent { + //Resource name of the event ? + string name = 1; + EventType event_type = 2; + oneof derivedEvent { + NewPartiesAvailableEvent new_parties_available_event = 3; + } +} +message EventSubscription { + EventType type = 2; +} +message ListEventSubscriptionsRequest { + //Resource name of parent to the subscription list (The member) + string parent = 1; + int32 page_size = 2; + string page_token = 3; +} +message ListEventSubscriptionsResponse { + repeated EventSubscription subscriptions = 1; + string next_page_token = 2; +} +message EventSubscriptionRequest { + //Resource name of the parent to the subscription list (The member) + string parent = 1; + EventSubscription event_subscription = 2; +} +message DeleteEventSubscriptionRequest { + //Resource name of the subscription to delete + string parent = 1; + EventType type = 2; +} +message EventSubscriptionListRequest { + //Resource name of the parent to the subscription list (The member) + string parent = 1; + repeated EventSubscription event_subscriptions = 2; +} +message EventSubscriptionListResponse { + repeated EventSubscription event_subscriptions = 1; +} +message DeleteAllEventSubscriptionsRequest { + //Resource name of the parent to the subscription list (the member) + string parent = 1; +} +message GetEventsRequest { + //Resource name of the parent to the event stream (the member) + string parent = 1; +} \ No newline at end of file diff --git a/Src/Services/SignalService.cs b/Src/Services/SignalService.cs new file mode 100644 index 0000000..c7cab5f --- /dev/null +++ b/Src/Services/SignalService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Grpc.Core; +using Microsoft.Extensions.Logging; + +namespace aurora_cradle_sharp +{ + public class SignalService : Signal.SignalBase + { + private readonly ILogger _logger; + public SignalService(ILogger logger) + { + _logger = logger; + } + + } +} diff --git a/Src/Startup.cs b/Src/Startup.cs new file mode 100644 index 0000000..5607904 --- /dev/null +++ b/Src/Startup.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace aurora_cradle_sharp +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + services.AddGrpc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGrpcService(); + + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("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"); + }); + }); + } + } +} diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..fe20c40 --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Grpc": "Information", + "Microsoft": "Information" + } + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..df549a7 --- /dev/null +++ b/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "Kestrel": { + "EndpointDefaults": { + "Protocols": "Http1" + } + } +} diff --git a/aurora-cradle-sharp.csproj b/aurora-cradle-sharp.csproj new file mode 100644 index 0000000..2b41fe9 --- /dev/null +++ b/aurora-cradle-sharp.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp3.1 + + + + + + + + + + + diff --git a/workspace.code-workspace b/workspace.code-workspace new file mode 100644 index 0000000..a0878cd --- /dev/null +++ b/workspace.code-workspace @@ -0,0 +1,12 @@ +{ + "folders": [ + { + "path": "." + } + ], +"settings": { + "files.exclude": { + "**/obj": true + } +} +} From 91d0a55d5ef99639c73521d27085356750c5b31e Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Thu, 4 Mar 2021 12:08:53 -0500 Subject: [PATCH 03/10] Re-arranging files to add test project. Adding WIP cursor list --- AuroraSignal.test/AuroraSignal.test.csproj | 26 +++++ AuroraSignal.test/CursorList.test.cs | 70 ++++++++++++++ AuroraSignal/Src/CursorList.cs | 94 +++++++++++++++++++ {Src => AuroraSignal/Src}/Program.cs | 2 +- {Src => AuroraSignal/Src}/Protos/signal.proto | 36 ++++++- AuroraSignal/Src/Services/Signal/Events.cs | 7 ++ AuroraSignal/Src/Services/Signal/Party.cs | 34 +++++++ .../Src/Services/Signal}/SignalService.cs | 7 +- {Src => AuroraSignal/Src}/Startup.cs | 3 +- .../appsettings.Development.json | 0 .../appsettings.json | 0 .../aurora-cradle-sharp.csproj | 0 12 files changed, 272 insertions(+), 7 deletions(-) create mode 100644 AuroraSignal.test/AuroraSignal.test.csproj create mode 100644 AuroraSignal.test/CursorList.test.cs create mode 100644 AuroraSignal/Src/CursorList.cs rename {Src => AuroraSignal/Src}/Program.cs (93%) rename {Src => AuroraSignal/Src}/Protos/signal.proto (97%) create mode 100644 AuroraSignal/Src/Services/Signal/Events.cs create mode 100644 AuroraSignal/Src/Services/Signal/Party.cs rename {Src/Services => AuroraSignal/Src/Services/Signal}/SignalService.cs (63%) rename {Src => AuroraSignal/Src}/Startup.cs (94%) rename appsettings.Development.json => AuroraSignal/appsettings.Development.json (100%) rename appsettings.json => AuroraSignal/appsettings.json (100%) rename aurora-cradle-sharp.csproj => AuroraSignal/aurora-cradle-sharp.csproj (100%) diff --git a/AuroraSignal.test/AuroraSignal.test.csproj b/AuroraSignal.test/AuroraSignal.test.csproj new file mode 100644 index 0000000..e343af3 --- /dev/null +++ b/AuroraSignal.test/AuroraSignal.test.csproj @@ -0,0 +1,26 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraSignal.test/CursorList.test.cs new file mode 100644 index 0000000..913b1ec --- /dev/null +++ b/AuroraSignal.test/CursorList.test.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using Xunit; +using Aurora; +using Aurora.Services.Signal; + + +namespace AuroraSignal.test +{ + public class CursorListTest + { + [Theory()] + [InlineData(SortDirection.Asc)] + [InlineData(SortDirection.Desc)] + public void CursorListSortOnStringValue(SortDirection direction) + { + CursorList cursor = new CursorList(); + cursor.Add(new Party(){Name = "asdf", PartyId = "1111"}); + cursor.Add(new Party(){Name = "bsdf", PartyId = "2222"}); + cursor.Add(new Party(){Name = "csdf", PartyId = "3333"}); + + List result = cursor.WithSort("Name", direction).Get(); + + if(direction == SortDirection.Desc) + { + Assert.Collection(cursor, + item => item.Name.Equals("asdf"), + item => item.Name.Equals("bsdf"), + item => item.Name.Equals("csdf")); + } + else + { + Assert.Collection(cursor, + item => item.Name.Equals("csdf"), + item => item.Name.Equals("bsdf"), + item => item.Name.Equals("asdf")); + + } + } + + [Theory()] + [InlineData(SortDirection.Asc)] + [InlineData(SortDirection.Desc)] + public void CursorListSortOnIntValue(SortDirection direction) + { + CursorList cursor = new CursorList(); + cursor.Add(new {Name = "asdf", PartyId = 1111}); + cursor.Add(new {Name = "bsdf", PartyId = 2222}); + cursor.Add(new {Name = "csdf", PartyId = 3333}); + + List result = cursor.WithSort("PartyId", direction).Get(); + + if(direction == SortDirection.Desc) + { + Assert.Collection(cursor, + item => item.Equals(new {Name = "asdf", PartyId = 1111}), + item => item.Equals(new {Name = "bsdf", PartyId = 2222}), + item => item.Equals(new {Name = "csdf", PartyId = 3333})); + } + else + { + Assert.Collection(cursor, + item => item.Equals(new {Name = "csdf", PartyId = 3333}), + item => item.Equals(new {Name = "bsdf", PartyId = 2222}), + item => item.Equals(new {Name = "asdf", PartyId = 1111})); + + } + } + } +} diff --git a/AuroraSignal/Src/CursorList.cs b/AuroraSignal/Src/CursorList.cs new file mode 100644 index 0000000..3a29106 --- /dev/null +++ b/AuroraSignal/Src/CursorList.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; + +namespace Aurora +{ + public enum SortDirection { + Asc, + Desc, + } + + public class CursorList : List + { + private string _orderBy; + private SortDirection _direction; + private string _previousPageToken; + private string _nextPageToken; + private int _pageSize; + + public CursorList(){ + this._direction = SortDirection.Desc; + this._orderBy = string.Empty; + this._previousPageToken = string.Empty; + this._nextPageToken = string.Empty; + this._pageSize = 10; + } + + public CursorList WithNextPage(string nextPageToken){ + this._nextPageToken = nextPageToken; + return this; + } + + public CursorList WithPreviousPage(string prevPageToken){ + this._previousPageToken = prevPageToken; + return this; + } + + public CursorList WithSort(string orderBy, SortDirection direction ) { + this._orderBy = orderBy; + this._direction = direction; + return this; + } + + public CursorList WithSize(int size){ + this._pageSize = size; + return this; + } + + public List Get(){ + if(this._nextPageToken != string.Empty && this._previousPageToken != string.Empty){ + throw new System.InvalidOperationException("Cannot specify both next and previous page tokens"); + } + + List tmpList = new List(this); + + + tmpList.Sort(delegate(T first, T second){ + object firstVal = first.GetType().GetProperty(this._orderBy).GetValue(first, null); + object secondVal = first.GetType().GetProperty(this._orderBy).GetValue(second, null); + int compare = 0; + + if(firstVal == null && secondVal == null) + { + compare = 0; + } + else if(firstVal == null) + { + compare = 1; + } + else if(secondVal == null) + { + compare = -1; + } + else + { + + // Determine number or string types + if(firstVal is string) + { + string firstStr = firstVal as string; + string secondStr = secondVal as string; + compare = firstStr.CompareTo(secondStr); + } else if(firstVal is int) + { + int? firstInt = firstVal as int?; + int? secondInt = secondVal as int?; + compare = firstInt > secondInt ? 1 : -1; + } + } + return this._direction == SortDirection.Asc ? compare : compare * -1; + }); + + return tmpList.GetRange(0, this._pageSize > tmpList.Count ? tmpList.Count : this._pageSize); + } + } +} \ No newline at end of file diff --git a/Src/Program.cs b/AuroraSignal/Src/Program.cs similarity index 93% rename from Src/Program.cs rename to AuroraSignal/Src/Program.cs index e35ec24..6ffeaba 100644 --- a/Src/Program.cs +++ b/AuroraSignal/Src/Program.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; -namespace aurora_cradle_sharp +namespace Aurora { public class Program { diff --git a/Src/Protos/signal.proto b/AuroraSignal/Src/Protos/signal.proto similarity index 97% rename from Src/Protos/signal.proto rename to AuroraSignal/Src/Protos/signal.proto index 8ba2d23..66c12ee 100644 --- a/Src/Protos/signal.proto +++ b/AuroraSignal/Src/Protos/signal.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option csharp_namespace = "aurora_cradle_sharp"; +option csharp_namespace = "Aurora.Services.Signal"; package signal; @@ -9,28 +9,38 @@ import "google/protobuf/timestamp.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/empty.proto"; -service Signal{ + +service Signal { //************** //Party Resource //************** //Get Party rpc ListParties(ListPartiesRequest) returns (ListPartiesResponse); + rpc GetParty(GetPartyRequest) returns (Party); + rpc UpdateParty(UpdatePartyRequest) returns (Party); + rpc CreateParty(CreatePartyRequest) returns (Party); + rpc DeleteParty(DeletePartyRequest) returns (google.protobuf.Empty); + + //*************************** //EventSubscriptions Resource //*************************** //List rpc ListEventSubscriptions(ListEventSubscriptionsRequest) returns (ListEventSubscriptionsResponse); + //Create rpc SubscribeToEvent(EventSubscriptionRequest) returns (EventSubscription); //Delete rpc DeleteEventSubscription(DeleteEventSubscriptionRequest) returns (google.protobuf.Empty); + //CUSTOM: Create EventSubscription List rpc SubscribeToEvents(EventSubscriptionListRequest) returns (EventSubscriptionListResponse); + //CUSTOM: Delete all rpc DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest) returns (google.protobuf.Empty); @@ -40,6 +50,7 @@ service Signal{ //Get rpc GetEventStream(GetEventsRequest) returns (stream BaseEvent) {}; } + message Party { //The resource name of the party string name = 1; @@ -49,38 +60,48 @@ message Party { string host_ip = 5; google.protobuf.Timestamp created_on = 6; } + message PartyListItem { string name = 1; string party_id = 2; } + message ListPartiesRequest { int32 page_size = 1; string page_token = 2; } + message ListPartiesResponse { repeated PartyListItem parties = 1; string next_page_token = 2; } + message GetPartyRequest { string party_id = 1; } + message CreatePartyRequest { string party_id = 1; Party party = 2; } + message DeletePartyRequest { string party_id = 1; } + message UpdatePartyRequest { Party party = 1; google.protobuf.FieldMask update_mask = 2; } + /* Event Types */ enum EventType { NewPartiesAvailable = 0; } + message NewPartiesAvailableEvent { } + message BaseEvent { //Resource name of the event ? string name = 1; @@ -89,42 +110,51 @@ message BaseEvent { NewPartiesAvailableEvent new_parties_available_event = 3; } } + message EventSubscription { EventType type = 2; } + message ListEventSubscriptionsRequest { //Resource name of parent to the subscription list (The member) string parent = 1; int32 page_size = 2; string page_token = 3; } + message ListEventSubscriptionsResponse { repeated EventSubscription subscriptions = 1; string next_page_token = 2; } + message EventSubscriptionRequest { //Resource name of the parent to the subscription list (The member) string parent = 1; EventSubscription event_subscription = 2; } + message DeleteEventSubscriptionRequest { //Resource name of the subscription to delete string parent = 1; EventType type = 2; } + message EventSubscriptionListRequest { //Resource name of the parent to the subscription list (The member) string parent = 1; repeated EventSubscription event_subscriptions = 2; } + message EventSubscriptionListResponse { repeated EventSubscription event_subscriptions = 1; } + message DeleteAllEventSubscriptionsRequest { //Resource name of the parent to the subscription list (the member) string parent = 1; } + message GetEventsRequest { //Resource name of the parent to the event stream (the member) string parent = 1; -} \ No newline at end of file +} diff --git a/AuroraSignal/Src/Services/Signal/Events.cs b/AuroraSignal/Src/Services/Signal/Events.cs new file mode 100644 index 0000000..41e7034 --- /dev/null +++ b/AuroraSignal/Src/Services/Signal/Events.cs @@ -0,0 +1,7 @@ +namespace Aurora.Services.Signal +{ + public partial class SignalService : Signal.SignalBase + { + + } +} \ No newline at end of file diff --git a/AuroraSignal/Src/Services/Signal/Party.cs b/AuroraSignal/Src/Services/Signal/Party.cs new file mode 100644 index 0000000..cccf8f8 --- /dev/null +++ b/AuroraSignal/Src/Services/Signal/Party.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Google.Protobuf.WellKnownTypes; +using Grpc.Core; + +namespace Aurora.Services.Signal +{ + public partial class SignalService : Signal.SignalBase + { + public override Task CreateParty(CreatePartyRequest request, ServerCallContext context) + { + return base.CreateParty(request, context); + } + + public override Task DeleteParty(DeletePartyRequest request, ServerCallContext context) + { + return base.DeleteParty(request, context); + } + + public override Task ListParties(ListPartiesRequest request, ServerCallContext context) + { + return base.ListParties(request, context); + } + + public override Task GetParty(GetPartyRequest request, ServerCallContext context) + { + return base.GetParty(request, context); + } + + public override Task UpdateParty(UpdatePartyRequest request, ServerCallContext context) + { + return base.UpdateParty(request, context); + } + } +} \ No newline at end of file diff --git a/Src/Services/SignalService.cs b/AuroraSignal/Src/Services/Signal/SignalService.cs similarity index 63% rename from Src/Services/SignalService.cs rename to AuroraSignal/Src/Services/Signal/SignalService.cs index c7cab5f..6e68a67 100644 --- a/Src/Services/SignalService.cs +++ b/AuroraSignal/Src/Services/Signal/SignalService.cs @@ -5,14 +5,17 @@ using System.Threading.Tasks; using Grpc.Core; using Microsoft.Extensions.Logging; -namespace aurora_cradle_sharp +namespace Aurora.Services.Signal { - public class SignalService : Signal.SignalBase + public partial class SignalService : Signal.SignalBase { private readonly ILogger _logger; + + private CursorList _partyList; public SignalService(ILogger logger) { _logger = logger; + this._partyList = new CursorList(); } } diff --git a/Src/Startup.cs b/AuroraSignal/Src/Startup.cs similarity index 94% rename from Src/Startup.cs rename to AuroraSignal/Src/Startup.cs index 5607904..2ffb350 100644 --- a/Src/Startup.cs +++ b/AuroraSignal/Src/Startup.cs @@ -7,8 +7,9 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Aurora.Services.Signal; -namespace aurora_cradle_sharp +namespace Aurora { public class Startup { diff --git a/appsettings.Development.json b/AuroraSignal/appsettings.Development.json similarity index 100% rename from appsettings.Development.json rename to AuroraSignal/appsettings.Development.json diff --git a/appsettings.json b/AuroraSignal/appsettings.json similarity index 100% rename from appsettings.json rename to AuroraSignal/appsettings.json diff --git a/aurora-cradle-sharp.csproj b/AuroraSignal/aurora-cradle-sharp.csproj similarity index 100% rename from aurora-cradle-sharp.csproj rename to AuroraSignal/aurora-cradle-sharp.csproj From b61ffde4c92642d8ec5d6a0a053c657af5e881d4 Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 11:56:51 -0500 Subject: [PATCH 04/10] WIP --- AuroraSignal.test/CursorList.test.cs | 58 +++------ AuroraSignal/Src/Augments/Party.cs | 9 ++ AuroraSignal/Src/Cursor/Cursor.cs | 112 ++++++++++++++++++ AuroraSignal/Src/Cursor/CursorList.cs | 32 +++++ AuroraSignal/Src/Cursor/CursorObject.cs | 9 ++ AuroraSignal/Src/Cursor/CursorResult.cs | 25 ++++ AuroraSignal/Src/CursorList.cs | 94 --------------- AuroraSignal/Src/Protos/signal.proto | 4 +- .../Src/Services/Signal/SignalService.cs | 1 + AuroraSignal/Src/Utils/HashUtil.cs | 25 ++++ workspace.code-workspace | 5 +- 11 files changed, 234 insertions(+), 140 deletions(-) create mode 100644 AuroraSignal/Src/Augments/Party.cs create mode 100644 AuroraSignal/Src/Cursor/Cursor.cs create mode 100644 AuroraSignal/Src/Cursor/CursorList.cs create mode 100644 AuroraSignal/Src/Cursor/CursorObject.cs create mode 100644 AuroraSignal/Src/Cursor/CursorResult.cs delete mode 100644 AuroraSignal/Src/CursorList.cs create mode 100644 AuroraSignal/Src/Utils/HashUtil.cs diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraSignal.test/CursorList.test.cs index 913b1ec..7780280 100644 --- a/AuroraSignal.test/CursorList.test.cs +++ b/AuroraSignal.test/CursorList.test.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; using Xunit; using Aurora; using Aurora.Services.Signal; +using Aurora.Cursor; namespace AuroraSignal.test @@ -14,57 +13,30 @@ namespace AuroraSignal.test [InlineData(SortDirection.Desc)] public void CursorListSortOnStringValue(SortDirection direction) { - CursorList cursor = new CursorList(); - cursor.Add(new Party(){Name = "asdf", PartyId = "1111"}); - cursor.Add(new Party(){Name = "bsdf", PartyId = "2222"}); - cursor.Add(new Party(){Name = "csdf", PartyId = "3333"}); + CursorList list = new CursorList(); + list.Add(new Party() { Name = "asdf", Id = "1111" }); + list.Add(new Party() { Name = "bsdf", Id = "2222" }); + list.Add(new Party() { Name = "csdf", Id = "3333" }); - List result = cursor.WithSort("Name", direction).Get(); + CursorResult result = new Cursor(ref list) + .WithSort(item => item.Value.Name, direction) + .GetNextPage(); - if(direction == SortDirection.Desc) + if (direction == SortDirection.Desc) { - Assert.Collection(cursor, - item => item.Name.Equals("asdf"), - item => item.Name.Equals("bsdf"), + Assert.Collection(result.Result, + item => item.Name.Equals("asdf"), + item => item.Name.Equals("bsdf"), item => item.Name.Equals("csdf")); } else { - Assert.Collection(cursor, - item => item.Name.Equals("csdf"), - item => item.Name.Equals("bsdf"), + Assert.Collection(result.Result, + item => item.Name.Equals("csdf"), + item => item.Name.Equals("bsdf"), item => item.Name.Equals("asdf")); } } - - [Theory()] - [InlineData(SortDirection.Asc)] - [InlineData(SortDirection.Desc)] - public void CursorListSortOnIntValue(SortDirection direction) - { - CursorList cursor = new CursorList(); - cursor.Add(new {Name = "asdf", PartyId = 1111}); - cursor.Add(new {Name = "bsdf", PartyId = 2222}); - cursor.Add(new {Name = "csdf", PartyId = 3333}); - - List result = cursor.WithSort("PartyId", direction).Get(); - - if(direction == SortDirection.Desc) - { - Assert.Collection(cursor, - item => item.Equals(new {Name = "asdf", PartyId = 1111}), - item => item.Equals(new {Name = "bsdf", PartyId = 2222}), - item => item.Equals(new {Name = "csdf", PartyId = 3333})); - } - else - { - Assert.Collection(cursor, - item => item.Equals(new {Name = "csdf", PartyId = 3333}), - item => item.Equals(new {Name = "bsdf", PartyId = 2222}), - item => item.Equals(new {Name = "asdf", PartyId = 1111})); - - } - } } } diff --git a/AuroraSignal/Src/Augments/Party.cs b/AuroraSignal/Src/Augments/Party.cs new file mode 100644 index 0000000..52c697f --- /dev/null +++ b/AuroraSignal/Src/Augments/Party.cs @@ -0,0 +1,9 @@ +using Aurora.Cursor; + +namespace Aurora.Services.Signal +{ + public partial class Party : ICursorObject + { + } +} + diff --git a/AuroraSignal/Src/Cursor/Cursor.cs b/AuroraSignal/Src/Cursor/Cursor.cs new file mode 100644 index 0000000..b740951 --- /dev/null +++ b/AuroraSignal/Src/Cursor/Cursor.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +#nullable enable +namespace Aurora.Cursor +{ + public enum SortDirection + { + Asc, + Desc, + } + + public class Cursor where T : ICursorObject + { + private CursorList _list; + + private string? _previousPageToken; + private string? _nextPageToken; + private int _pageSize; + private Func, string> _sortDelgate; + private SortDirection _direction; + public Cursor(ref CursorList list) + { + this._list = list; + this._previousPageToken = string.Empty; + this._nextPageToken = string.Empty; + this._pageSize = 10; + this._sortDelgate = delegate (KeyValuePair item) + { + return item.Value.Id; + }; + } + + public CursorResult GetNextPage() + { + List> tmpList; + + // Sort reference list + if (this._direction == SortDirection.Desc) + { + tmpList = this._list.OrderByDescending(this._sortDelgate).ToList(); + + } + else + { + tmpList = this._list.OrderBy(this._sortDelgate).ToList(); + } + + if (tmpList == null) + { + throw new System.NullReferenceException(); + } + + int startIdx = 0; + if (!string.IsNullOrEmpty(this._nextPageToken)) + { + // TODO find another way to index into the list that's not a regular array search + startIdx = tmpList.FindIndex(item => item.Key == this._nextPageToken); + } + + int endIdx = startIdx + this._pageSize; + + List selection = new List(); + + // Get page + for (int i = startIdx; i < tmpList.Count && i < endIdx; i++) + { + selection.Add(tmpList.ElementAt(i).Value); + } + + return new CursorResult + { + NextPageToken = selection[selection.Count - 1].Id, + PrevPageToken = selection[0].Id, + Count = this._list.Count, + Result = selection + }; + } + + public CursorResult GetPreviousPage() + { + throw new NotImplementedException(); + } + + public Cursor WithNextPage(string nextPageToken) + { + this._nextPageToken = nextPageToken; + return this; + } + + public Cursor WithPreviousPage(string prevPageToken) + { + this._previousPageToken = prevPageToken; + return this; + } + + public Cursor WithSort(Func, string> sortDelegate, SortDirection direction) + { + this._sortDelgate = sortDelegate; + this._direction = direction; + return this; + } + + public Cursor WithSize(int size) + { + this._pageSize = size; + return this; + } + } + +} \ No newline at end of file diff --git a/AuroraSignal/Src/Cursor/CursorList.cs b/AuroraSignal/Src/Cursor/CursorList.cs new file mode 100644 index 0000000..fbff1f3 --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorList.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Collections; +using System; +using System.Linq; +using Aurora.Utils; + +#nullable enable +namespace Aurora.Cursor +{ + + public class CursorList : SortedList where T : ICursorObject + { + + public CursorList() + { + } + + public CursorList Add(T item) + { + string itemHashId = HashUtil.GetHash(new string[] { item.Id, item.GetHashCode().ToString() }).ToString(); + bool res = this.TryAdd(itemHashId, item); + + if (res == false) + { + throw new System.Exception("Failed to add item to cursor list"); + } + return this; + } + + + } +} \ No newline at end of file diff --git a/AuroraSignal/Src/Cursor/CursorObject.cs b/AuroraSignal/Src/Cursor/CursorObject.cs new file mode 100644 index 0000000..cca1779 --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorObject.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Aurora.Cursor +{ + public interface ICursorObject + { + string Id { get; set; } + } +} diff --git a/AuroraSignal/Src/Cursor/CursorResult.cs b/AuroraSignal/Src/Cursor/CursorResult.cs new file mode 100644 index 0000000..ab50c6a --- /dev/null +++ b/AuroraSignal/Src/Cursor/CursorResult.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Aurora.Cursor +{ + public class CursorResult + { + public CursorResult() + { + Result = new List(); + } + + public CursorResult(CursorResult cpy) + { + NextPageToken = cpy.NextPageToken; + PrevPageToken = cpy.PrevPageToken; + Result = cpy.Result; + Count = cpy.Count; + } + + public string NextPageToken { get; set; } + public string PrevPageToken { get; set; } + public List Result { get; set; } + public int Count { get; set; } + } +} diff --git a/AuroraSignal/Src/CursorList.cs b/AuroraSignal/Src/CursorList.cs deleted file mode 100644 index 3a29106..0000000 --- a/AuroraSignal/Src/CursorList.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Collections.Generic; - -namespace Aurora -{ - public enum SortDirection { - Asc, - Desc, - } - - public class CursorList : List - { - private string _orderBy; - private SortDirection _direction; - private string _previousPageToken; - private string _nextPageToken; - private int _pageSize; - - public CursorList(){ - this._direction = SortDirection.Desc; - this._orderBy = string.Empty; - this._previousPageToken = string.Empty; - this._nextPageToken = string.Empty; - this._pageSize = 10; - } - - public CursorList WithNextPage(string nextPageToken){ - this._nextPageToken = nextPageToken; - return this; - } - - public CursorList WithPreviousPage(string prevPageToken){ - this._previousPageToken = prevPageToken; - return this; - } - - public CursorList WithSort(string orderBy, SortDirection direction ) { - this._orderBy = orderBy; - this._direction = direction; - return this; - } - - public CursorList WithSize(int size){ - this._pageSize = size; - return this; - } - - public List Get(){ - if(this._nextPageToken != string.Empty && this._previousPageToken != string.Empty){ - throw new System.InvalidOperationException("Cannot specify both next and previous page tokens"); - } - - List tmpList = new List(this); - - - tmpList.Sort(delegate(T first, T second){ - object firstVal = first.GetType().GetProperty(this._orderBy).GetValue(first, null); - object secondVal = first.GetType().GetProperty(this._orderBy).GetValue(second, null); - int compare = 0; - - if(firstVal == null && secondVal == null) - { - compare = 0; - } - else if(firstVal == null) - { - compare = 1; - } - else if(secondVal == null) - { - compare = -1; - } - else - { - - // Determine number or string types - if(firstVal is string) - { - string firstStr = firstVal as string; - string secondStr = secondVal as string; - compare = firstStr.CompareTo(secondStr); - } else if(firstVal is int) - { - int? firstInt = firstVal as int?; - int? secondInt = secondVal as int?; - compare = firstInt > secondInt ? 1 : -1; - } - } - return this._direction == SortDirection.Asc ? compare : compare * -1; - }); - - return tmpList.GetRange(0, this._pageSize > tmpList.Count ? tmpList.Count : this._pageSize); - } - } -} \ No newline at end of file diff --git a/AuroraSignal/Src/Protos/signal.proto b/AuroraSignal/Src/Protos/signal.proto index 66c12ee..5d62e9c 100644 --- a/AuroraSignal/Src/Protos/signal.proto +++ b/AuroraSignal/Src/Protos/signal.proto @@ -54,7 +54,7 @@ service Signal { message Party { //The resource name of the party string name = 1; - string party_id = 2; + string id = 2; string display_name = 3; string description = 4; string host_ip = 5; @@ -63,7 +63,7 @@ message Party { message PartyListItem { string name = 1; - string party_id = 2; + string id = 2; } message ListPartiesRequest { diff --git a/AuroraSignal/Src/Services/Signal/SignalService.cs b/AuroraSignal/Src/Services/Signal/SignalService.cs index 6e68a67..8a59f50 100644 --- a/AuroraSignal/Src/Services/Signal/SignalService.cs +++ b/AuroraSignal/Src/Services/Signal/SignalService.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Grpc.Core; using Microsoft.Extensions.Logging; +using Aurora.Cursor; namespace Aurora.Services.Signal { diff --git a/AuroraSignal/Src/Utils/HashUtil.cs b/AuroraSignal/Src/Utils/HashUtil.cs new file mode 100644 index 0000000..0644870 --- /dev/null +++ b/AuroraSignal/Src/Utils/HashUtil.cs @@ -0,0 +1,25 @@ +using System.Security.Cryptography; +using System.Text; +using System; + +namespace Aurora.Utils +{ + public class HashUtil + { + public static Guid GetHash(string[] inputs) + { + string input = ""; + foreach (string str in inputs) + { + input += str; + } + + byte[] stringbytes = Encoding.UTF8.GetBytes(input); + byte[] hashedBytes = new System.Security.Cryptography + .SHA1CryptoServiceProvider() + .ComputeHash(stringbytes); + Array.Resize(ref hashedBytes, 16); + return new Guid(hashedBytes); + } + } +} diff --git a/workspace.code-workspace b/workspace.code-workspace index a0878cd..d491373 100644 --- a/workspace.code-workspace +++ b/workspace.code-workspace @@ -7,6 +7,9 @@ "settings": { "files.exclude": { "**/obj": true - } + }, + "dotnet-test-explorer.testProjectPath": "./AuroraSignal.test", + "editor.formatOnSave": true, + "editor.defaultFormatter": "ms-dotnettools.csharp" } } From 24fd683cb7252304d46e21787b023b7f2405b66b Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 14:30:25 -0500 Subject: [PATCH 05/10] Adding cursor size tests --- AuroraSignal.test/AuroraSignal.test.csproj | 1 + AuroraSignal.test/CursorList.test.cs | 49 ++++++++++++++++++++-- AuroraSignal/Src/Cursor/Cursor.cs | 22 +++++----- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/AuroraSignal.test/AuroraSignal.test.csproj b/AuroraSignal.test/AuroraSignal.test.csproj index e343af3..2f7facf 100644 --- a/AuroraSignal.test/AuroraSignal.test.csproj +++ b/AuroraSignal.test/AuroraSignal.test.csproj @@ -7,6 +7,7 @@ + diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraSignal.test/CursorList.test.cs index 7780280..9a51457 100644 --- a/AuroraSignal.test/CursorList.test.cs +++ b/AuroraSignal.test/CursorList.test.cs @@ -2,6 +2,7 @@ using Xunit; using Aurora; using Aurora.Services.Signal; using Aurora.Cursor; +using Faker; namespace AuroraSignal.test @@ -14,9 +15,9 @@ namespace AuroraSignal.test public void CursorListSortOnStringValue(SortDirection direction) { CursorList list = new CursorList(); - list.Add(new Party() { Name = "asdf", Id = "1111" }); - list.Add(new Party() { Name = "bsdf", Id = "2222" }); - list.Add(new Party() { Name = "csdf", Id = "3333" }); + list.Add(new Party() { Name = "asdf", Id = Faker.RandomNumber.Next().ToString() }); + list.Add(new Party() { Name = "bsdf", Id = Faker.RandomNumber.Next().ToString() }); + list.Add(new Party() { Name = "csdf", Id = Faker.RandomNumber.Next().ToString() }); CursorResult result = new Cursor(ref list) .WithSort(item => item.Value.Name, direction) @@ -38,5 +39,47 @@ namespace AuroraSignal.test } } + + [Theory()] + [InlineData(2)] + [InlineData(10)] + [InlineData(49)] + [InlineData(51)] + [InlineData(-1)] + public void CursorListSizeTest(int size) + { + int numOfItems = 50; + CursorList list = new CursorList(); + + // Add items to cursor list + for (int i = 0; i < numOfItems; i++) + { + list.Add(new Party() + { + Name = string.Join(" ", + Faker.Lorem.Words(2)), + Id = Faker.RandomNumber.Next().ToString() + }); + } + + Cursor cursor = new Cursor(ref list); + if (size < 0) + { + Assert.Throws(() => + { + cursor.WithSize(size).GetNextPage(); + }); + } + else if (size > numOfItems) + { + CursorResult res = cursor.WithSize(size).GetNextPage(); + Assert.Equal(res.Result.Count, numOfItems); + } + else if (size < numOfItems && size > 0) + { + CursorResult res = cursor.WithSize(size).GetNextPage(); + Assert.Equal(res.Result.Count, size); + } + } } } diff --git a/AuroraSignal/Src/Cursor/Cursor.cs b/AuroraSignal/Src/Cursor/Cursor.cs index b740951..2b93df9 100644 --- a/AuroraSignal/Src/Cursor/Cursor.cs +++ b/AuroraSignal/Src/Cursor/Cursor.cs @@ -34,6 +34,10 @@ namespace Aurora.Cursor public CursorResult GetNextPage() { + if (this._pageSize < 0) + { + throw new InvalidOperationException("Page Size must be greater than zero"); + } List> tmpList; // Sort reference list @@ -61,20 +65,14 @@ namespace Aurora.Cursor int endIdx = startIdx + this._pageSize; - List selection = new List(); - - // Get page - for (int i = startIdx; i < tmpList.Count && i < endIdx; i++) - { - selection.Add(tmpList.ElementAt(i).Value); - } + List> selection = tmpList.GetRange(startIdx, this._pageSize > tmpList.Count ? tmpList.Count : this._pageSize); return new CursorResult { - NextPageToken = selection[selection.Count - 1].Id, - PrevPageToken = selection[0].Id, + NextPageToken = selection[selection.Count - 1].Key, + PrevPageToken = selection[0].Key, Count = this._list.Count, - Result = selection + Result = selection.ConvertAll(item => item.Value) }; } @@ -83,13 +81,13 @@ namespace Aurora.Cursor throw new NotImplementedException(); } - public Cursor WithNextPage(string nextPageToken) + public Cursor WithNextPageToken(string nextPageToken) { this._nextPageToken = nextPageToken; return this; } - public Cursor WithPreviousPage(string prevPageToken) + public Cursor WithPreviousPageToken(string prevPageToken) { this._previousPageToken = prevPageToken; return this; From 4a4cef8dd74cbb338ddc92821369a51ec8335037 Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 16:13:25 -0500 Subject: [PATCH 06/10] Adding pagination tests --- AuroraSignal.test/CursorList.test.cs | 84 +++++++++++++++++++++++++++- AuroraSignal/Src/Cursor/Cursor.cs | 21 +++++-- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraSignal.test/CursorList.test.cs index 9a51457..2faef15 100644 --- a/AuroraSignal.test/CursorList.test.cs +++ b/AuroraSignal.test/CursorList.test.cs @@ -1,8 +1,11 @@ using Xunit; -using Aurora; using Aurora.Services.Signal; using Aurora.Cursor; using Faker; +using System; +using System.Collections.Generic; +using System.Linq; + namespace AuroraSignal.test @@ -81,5 +84,84 @@ namespace AuroraSignal.test Assert.Equal(res.Result.Count, size); } } + + [Theory()] + [InlineData(2)] + [InlineData(10)] + [InlineData(3)] + public void CursorPaginationTest(int pageSize) + { + int numOfItems = 50; + CursorList list = new CursorList(); + + // Add items to cursor list + for (int i = 0; i < numOfItems; i++) + { + list.Add(new Party() + { + Name = string.Join(" ", + Faker.Lorem.Words(2)), + Id = Faker.RandomNumber.Next().ToString() + }); + } + + string pageToken = null; + Cursor cursor = new Cursor(ref list); + List pagedResults = new List(); + while (pageToken != string.Empty) + { + CursorResult res = cursor + .WithSize(pageSize) + .WithNextPageToken(pageToken) + .GetNextPage(); + + pagedResults.AddRange(res.Result); + pageToken = res.NextPageToken; + } + + Assert.Equal(pagedResults.Count, numOfItems); + } + + [Fact()] + + public void CursorPaginationWithSortTest() + { + int numOfItems = 50; + CursorList cursorList = new CursorList(); + + // Add items to cursor list + for (int i = 0; i < numOfItems; i++) + { + cursorList.Add(new Party() + { + Name = string.Join(" ", + Faker.Lorem.Words(2)), + Id = Faker.RandomNumber.Next().ToString() + }); + } + + var orderedList = cursorList.ToList().OrderBy(item => item.Value.Name).ToList().ConvertAll(item => item.Value); + + string pageToken = null; + Cursor cursor = new Cursor(ref cursorList); + List pagedResults = new List(); + while (pageToken != string.Empty) + { + CursorResult res = cursor + .WithSize(10) + .WithSort(item => item.Value.Name, SortDirection.Asc) + .WithNextPageToken(pageToken) + .GetNextPage(); + + pagedResults.AddRange(res.Result); + pageToken = res.NextPageToken; + } + + var list = cursorList.ToList(); + for (int i = 0; i < orderedList.Count; i++) + { + Assert.Equal(orderedList[i], pagedResults[i]); + } + } } } diff --git a/AuroraSignal/Src/Cursor/Cursor.cs b/AuroraSignal/Src/Cursor/Cursor.cs index 2b93df9..91db9ea 100644 --- a/AuroraSignal/Src/Cursor/Cursor.cs +++ b/AuroraSignal/Src/Cursor/Cursor.cs @@ -28,7 +28,7 @@ namespace Aurora.Cursor this._pageSize = 10; this._sortDelgate = delegate (KeyValuePair item) { - return item.Value.Id; + return item.Key; }; } @@ -60,17 +60,26 @@ namespace Aurora.Cursor if (!string.IsNullOrEmpty(this._nextPageToken)) { // TODO find another way to index into the list that's not a regular array search - startIdx = tmpList.FindIndex(item => item.Key == this._nextPageToken); + startIdx = tmpList.FindIndex(item => item.Key == this._nextPageToken) + 1; } - int endIdx = startIdx + this._pageSize; + int adjustedSize = this._pageSize; + if (startIdx + this._pageSize > tmpList.Count) + { + adjustedSize = this._pageSize - ((startIdx + _pageSize) - tmpList.Count); + } - List> selection = tmpList.GetRange(startIdx, this._pageSize > tmpList.Count ? tmpList.Count : this._pageSize); + + List> selection = new List>(); + if (adjustedSize != 0) + { + selection = tmpList.GetRange(startIdx, adjustedSize); + } return new CursorResult { - NextPageToken = selection[selection.Count - 1].Key, - PrevPageToken = selection[0].Key, + NextPageToken = this._pageSize == selection.Count ? selection[selection.Count - 1].Key : string.Empty, + PrevPageToken = string.Empty, Count = this._list.Count, Result = selection.ConvertAll(item => item.Value) }; From 6f73df0fb71611d879b96db1e3cbc5307f6482dc Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 16:50:54 -0500 Subject: [PATCH 07/10] Updated folder paths --- .../AuroraSignal.test.csproj | 4 ++-- {AuroraSignal.test => AuroraCradle.test}/CursorList.test.cs | 2 +- {AuroraSignal => AuroraCradle}/Src/Augments/Party.cs | 0 {AuroraSignal => AuroraCradle}/Src/Cursor/Cursor.cs | 0 {AuroraSignal => AuroraCradle}/Src/Cursor/CursorList.cs | 0 {AuroraSignal => AuroraCradle}/Src/Cursor/CursorObject.cs | 0 {AuroraSignal => AuroraCradle}/Src/Cursor/CursorResult.cs | 0 {AuroraSignal => AuroraCradle}/Src/Program.cs | 0 {AuroraSignal => AuroraCradle}/Src/Protos/signal.proto | 0 {AuroraSignal => AuroraCradle}/Src/Services/Signal/Events.cs | 0 {AuroraSignal => AuroraCradle}/Src/Services/Signal/Party.cs | 0 .../Src/Services/Signal/SignalService.cs | 0 {AuroraSignal => AuroraCradle}/Src/Startup.cs | 0 {AuroraSignal => AuroraCradle}/Src/Utils/HashUtil.cs | 0 {AuroraSignal => AuroraCradle}/appsettings.Development.json | 0 {AuroraSignal => AuroraCradle}/appsettings.json | 0 {AuroraSignal => AuroraCradle}/aurora-cradle-sharp.csproj | 0 workspace.code-workspace | 2 +- 18 files changed, 4 insertions(+), 4 deletions(-) rename {AuroraSignal.test => AuroraCradle.test}/AuroraSignal.test.csproj (90%) rename {AuroraSignal.test => AuroraCradle.test}/CursorList.test.cs (96%) rename {AuroraSignal => AuroraCradle}/Src/Augments/Party.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Cursor/Cursor.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Cursor/CursorList.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Cursor/CursorObject.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Cursor/CursorResult.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Program.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Protos/signal.proto (100%) rename {AuroraSignal => AuroraCradle}/Src/Services/Signal/Events.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Services/Signal/Party.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Services/Signal/SignalService.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Startup.cs (100%) rename {AuroraSignal => AuroraCradle}/Src/Utils/HashUtil.cs (100%) rename {AuroraSignal => AuroraCradle}/appsettings.Development.json (100%) rename {AuroraSignal => AuroraCradle}/appsettings.json (100%) rename {AuroraSignal => AuroraCradle}/aurora-cradle-sharp.csproj (100%) diff --git a/AuroraSignal.test/AuroraSignal.test.csproj b/AuroraCradle.test/AuroraSignal.test.csproj similarity index 90% rename from AuroraSignal.test/AuroraSignal.test.csproj rename to AuroraCradle.test/AuroraSignal.test.csproj index 2f7facf..8aa4944 100644 --- a/AuroraSignal.test/AuroraSignal.test.csproj +++ b/AuroraCradle.test/AuroraSignal.test.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/AuroraSignal.test/CursorList.test.cs b/AuroraCradle.test/CursorList.test.cs similarity index 96% rename from AuroraSignal.test/CursorList.test.cs rename to AuroraCradle.test/CursorList.test.cs index 2faef15..e62dac8 100644 --- a/AuroraSignal.test/CursorList.test.cs +++ b/AuroraCradle.test/CursorList.test.cs @@ -8,7 +8,7 @@ using System.Linq; -namespace AuroraSignal.test +namespace AuroraCradle.test { public class CursorListTest { diff --git a/AuroraSignal/Src/Augments/Party.cs b/AuroraCradle/Src/Augments/Party.cs similarity index 100% rename from AuroraSignal/Src/Augments/Party.cs rename to AuroraCradle/Src/Augments/Party.cs diff --git a/AuroraSignal/Src/Cursor/Cursor.cs b/AuroraCradle/Src/Cursor/Cursor.cs similarity index 100% rename from AuroraSignal/Src/Cursor/Cursor.cs rename to AuroraCradle/Src/Cursor/Cursor.cs diff --git a/AuroraSignal/Src/Cursor/CursorList.cs b/AuroraCradle/Src/Cursor/CursorList.cs similarity index 100% rename from AuroraSignal/Src/Cursor/CursorList.cs rename to AuroraCradle/Src/Cursor/CursorList.cs diff --git a/AuroraSignal/Src/Cursor/CursorObject.cs b/AuroraCradle/Src/Cursor/CursorObject.cs similarity index 100% rename from AuroraSignal/Src/Cursor/CursorObject.cs rename to AuroraCradle/Src/Cursor/CursorObject.cs diff --git a/AuroraSignal/Src/Cursor/CursorResult.cs b/AuroraCradle/Src/Cursor/CursorResult.cs similarity index 100% rename from AuroraSignal/Src/Cursor/CursorResult.cs rename to AuroraCradle/Src/Cursor/CursorResult.cs diff --git a/AuroraSignal/Src/Program.cs b/AuroraCradle/Src/Program.cs similarity index 100% rename from AuroraSignal/Src/Program.cs rename to AuroraCradle/Src/Program.cs diff --git a/AuroraSignal/Src/Protos/signal.proto b/AuroraCradle/Src/Protos/signal.proto similarity index 100% rename from AuroraSignal/Src/Protos/signal.proto rename to AuroraCradle/Src/Protos/signal.proto diff --git a/AuroraSignal/Src/Services/Signal/Events.cs b/AuroraCradle/Src/Services/Signal/Events.cs similarity index 100% rename from AuroraSignal/Src/Services/Signal/Events.cs rename to AuroraCradle/Src/Services/Signal/Events.cs diff --git a/AuroraSignal/Src/Services/Signal/Party.cs b/AuroraCradle/Src/Services/Signal/Party.cs similarity index 100% rename from AuroraSignal/Src/Services/Signal/Party.cs rename to AuroraCradle/Src/Services/Signal/Party.cs diff --git a/AuroraSignal/Src/Services/Signal/SignalService.cs b/AuroraCradle/Src/Services/Signal/SignalService.cs similarity index 100% rename from AuroraSignal/Src/Services/Signal/SignalService.cs rename to AuroraCradle/Src/Services/Signal/SignalService.cs diff --git a/AuroraSignal/Src/Startup.cs b/AuroraCradle/Src/Startup.cs similarity index 100% rename from AuroraSignal/Src/Startup.cs rename to AuroraCradle/Src/Startup.cs diff --git a/AuroraSignal/Src/Utils/HashUtil.cs b/AuroraCradle/Src/Utils/HashUtil.cs similarity index 100% rename from AuroraSignal/Src/Utils/HashUtil.cs rename to AuroraCradle/Src/Utils/HashUtil.cs diff --git a/AuroraSignal/appsettings.Development.json b/AuroraCradle/appsettings.Development.json similarity index 100% rename from AuroraSignal/appsettings.Development.json rename to AuroraCradle/appsettings.Development.json diff --git a/AuroraSignal/appsettings.json b/AuroraCradle/appsettings.json similarity index 100% rename from AuroraSignal/appsettings.json rename to AuroraCradle/appsettings.json diff --git a/AuroraSignal/aurora-cradle-sharp.csproj b/AuroraCradle/aurora-cradle-sharp.csproj similarity index 100% rename from AuroraSignal/aurora-cradle-sharp.csproj rename to AuroraCradle/aurora-cradle-sharp.csproj diff --git a/workspace.code-workspace b/workspace.code-workspace index d491373..1e373c0 100644 --- a/workspace.code-workspace +++ b/workspace.code-workspace @@ -8,7 +8,7 @@ "files.exclude": { "**/obj": true }, - "dotnet-test-explorer.testProjectPath": "./AuroraSignal.test", + "dotnet-test-explorer.testProjectPath": "./AuroraCradle.test", "editor.formatOnSave": true, "editor.defaultFormatter": "ms-dotnettools.csharp" } From e9065db23c13ffb67c13d2ea550ef0d9d87505fa Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 19:09:42 -0500 Subject: [PATCH 08/10] First pass at party service --- AuroraCradle.test/CursorList.test.cs | 14 ++--- AuroraCradle/Src/Cursor/Cursor.cs | 7 +++ AuroraCradle/Src/Cursor/CursorList.cs | 9 ++- AuroraCradle/Src/Protos/signal.proto | 7 +++ AuroraCradle/Src/Services/Signal/Party.cs | 55 +++++++++++++++++-- .../Src/Services/Signal/SignalService.cs | 1 - 6 files changed, 76 insertions(+), 17 deletions(-) diff --git a/AuroraCradle.test/CursorList.test.cs b/AuroraCradle.test/CursorList.test.cs index e62dac8..4a99d96 100644 --- a/AuroraCradle.test/CursorList.test.cs +++ b/AuroraCradle.test/CursorList.test.cs @@ -1,21 +1,17 @@ using Xunit; using Aurora.Services.Signal; using Aurora.Cursor; -using Faker; -using System; using System.Collections.Generic; using System.Linq; - - namespace AuroraCradle.test { public class CursorListTest { [Theory()] - [InlineData(SortDirection.Asc)] - [InlineData(SortDirection.Desc)] - public void CursorListSortOnStringValue(SortDirection direction) + [InlineData(Aurora.Cursor.SortDirection.Asc)] + [InlineData(Aurora.Cursor.SortDirection.Desc)] + public void CursorListSortOnStringValue(Aurora.Cursor.SortDirection direction) { CursorList list = new CursorList(); list.Add(new Party() { Name = "asdf", Id = Faker.RandomNumber.Next().ToString() }); @@ -26,7 +22,7 @@ namespace AuroraCradle.test .WithSort(item => item.Value.Name, direction) .GetNextPage(); - if (direction == SortDirection.Desc) + if (direction == Aurora.Cursor.SortDirection.Desc) { Assert.Collection(result.Result, item => item.Name.Equals("asdf"), @@ -149,7 +145,7 @@ namespace AuroraCradle.test { CursorResult res = cursor .WithSize(10) - .WithSort(item => item.Value.Name, SortDirection.Asc) + .WithSort(item => item.Value.Name, Aurora.Cursor.SortDirection.Asc) .WithNextPageToken(pageToken) .GetNextPage(); diff --git a/AuroraCradle/Src/Cursor/Cursor.cs b/AuroraCradle/Src/Cursor/Cursor.cs index 91db9ea..9a60991 100644 --- a/AuroraCradle/Src/Cursor/Cursor.cs +++ b/AuroraCradle/Src/Cursor/Cursor.cs @@ -109,6 +109,13 @@ namespace Aurora.Cursor return this; } + public Cursor WithSort(string key, SortDirection direction) + { + this._sortDelgate = (item) => key; + this._direction = direction; + return this; + } + public Cursor WithSize(int size) { this._pageSize = size; diff --git a/AuroraCradle/Src/Cursor/CursorList.cs b/AuroraCradle/Src/Cursor/CursorList.cs index fbff1f3..0dcbf04 100644 --- a/AuroraCradle/Src/Cursor/CursorList.cs +++ b/AuroraCradle/Src/Cursor/CursorList.cs @@ -17,8 +17,13 @@ namespace Aurora.Cursor public CursorList Add(T item) { - string itemHashId = HashUtil.GetHash(new string[] { item.Id, item.GetHashCode().ToString() }).ToString(); - bool res = this.TryAdd(itemHashId, item); + string id = item.Id; + if (item.Id == null) + { + id = HashUtil.GetHash(new string[] { item.GetHashCode().ToString() }).ToString(); + item.Id = id; + } + bool res = this.TryAdd(id, item); if (res == false) { diff --git a/AuroraCradle/Src/Protos/signal.proto b/AuroraCradle/Src/Protos/signal.proto index 5d62e9c..078630d 100644 --- a/AuroraCradle/Src/Protos/signal.proto +++ b/AuroraCradle/Src/Protos/signal.proto @@ -69,6 +69,13 @@ message PartyListItem { message ListPartiesRequest { int32 page_size = 1; string page_token = 2; + string order_by = 3; + SortDirection order_direction = 4; +} + +enum SortDirection { + Asc = 0; + Desc = 1; } message ListPartiesResponse { diff --git a/AuroraCradle/Src/Services/Signal/Party.cs b/AuroraCradle/Src/Services/Signal/Party.cs index cccf8f8..c044cde 100644 --- a/AuroraCradle/Src/Services/Signal/Party.cs +++ b/AuroraCradle/Src/Services/Signal/Party.cs @@ -1,34 +1,79 @@ using System.Threading.Tasks; using Google.Protobuf.WellKnownTypes; using Grpc.Core; +using Aurora.Cursor; +using Microsoft.Extensions.Logging; namespace Aurora.Services.Signal { public partial class SignalService : Signal.SignalBase { + private CursorList _partyList; + public override Task CreateParty(CreatePartyRequest request, ServerCallContext context) { - return base.CreateParty(request, context); + Party party = new Party(request.Party); + _partyList.Add(party); + + this._logger.LogInformation(string.Format("Added party with name: ${0} to parties", party.Name)); + + return Task.FromResult(party); } public override Task DeleteParty(DeletePartyRequest request, ServerCallContext context) { - return base.DeleteParty(request, context); + if (this._partyList.ContainsKey(request.PartyId)) + { + this._partyList.Remove(request.PartyId); + } + + this._logger.LogInformation(string.Format("Deleted party with id: ${0} to parties", request.PartyId)); + return Task.FromResult(new Empty()); } public override Task ListParties(ListPartiesRequest request, ServerCallContext context) { - return base.ListParties(request, context); + Cursor cursor = new Cursor(ref this._partyList); + + Aurora.Cursor.SortDirection direction = Aurora.Cursor.SortDirection.Asc; + if (request.OrderDirection == SortDirection.Desc) + { + direction = Aurora.Cursor.SortDirection.Desc; + } + + CursorResult res = cursor + .WithSort(request.OrderBy, direction) + .WithNextPageToken(request.PageToken) + .WithSize(request.PageSize) + .GetNextPage(); + + ListPartiesResponse response = new ListPartiesResponse() + { + NextPageToken = res.NextPageToken + }; + response.Parties.AddRange(res.Result.ConvertAll(party => new PartyListItem() + { + Name = party.Name, + Id = party.Id + })); + return Task.FromResult(response); } public override Task GetParty(GetPartyRequest request, ServerCallContext context) { - return base.GetParty(request, context); + Party party = new Party(); + + if (this._partyList.ContainsKey(request.PartyId)) + { + this._partyList.TryGetValue(request.PartyId, out party); + } + + return Task.FromResult(party); } public override Task UpdateParty(UpdatePartyRequest request, ServerCallContext context) { - return base.UpdateParty(request, context); + throw new System.NotImplementedException(); } } } \ No newline at end of file diff --git a/AuroraCradle/Src/Services/Signal/SignalService.cs b/AuroraCradle/Src/Services/Signal/SignalService.cs index 8a59f50..af4100a 100644 --- a/AuroraCradle/Src/Services/Signal/SignalService.cs +++ b/AuroraCradle/Src/Services/Signal/SignalService.cs @@ -12,7 +12,6 @@ namespace Aurora.Services.Signal { private readonly ILogger _logger; - private CursorList _partyList; public SignalService(ILogger logger) { _logger = logger; From 0945ccfd123e933ef5f734b1f33f9e8411a4bac5 Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 20:45:26 -0500 Subject: [PATCH 09/10] Wip --- AuroraCradle/Src/Services/Signal/SignalService.cs | 5 ----- AuroraCradle/Src/Startup.cs | 6 ++++++ AuroraCradle/aurora-cradle-sharp.csproj | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/AuroraCradle/Src/Services/Signal/SignalService.cs b/AuroraCradle/Src/Services/Signal/SignalService.cs index af4100a..3561c59 100644 --- a/AuroraCradle/Src/Services/Signal/SignalService.cs +++ b/AuroraCradle/Src/Services/Signal/SignalService.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Grpc.Core; using Microsoft.Extensions.Logging; using Aurora.Cursor; diff --git a/AuroraCradle/Src/Startup.cs b/AuroraCradle/Src/Startup.cs index 2ffb350..57b8520 100644 --- a/AuroraCradle/Src/Startup.cs +++ b/AuroraCradle/Src/Startup.cs @@ -18,6 +18,7 @@ namespace Aurora public void ConfigureServices(IServiceCollection services) { services.AddGrpc(); + services.AddGrpcReflection(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -26,6 +27,7 @@ namespace Aurora if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); + } app.UseRouting(); @@ -34,6 +36,10 @@ namespace Aurora { endpoints.MapGrpcService(); + if (env.IsDevelopment()) + { + endpoints.MapGrpcReflectionService(); + } endpoints.MapGet("/", async context => { await context.Response.WriteAsync("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"); diff --git a/AuroraCradle/aurora-cradle-sharp.csproj b/AuroraCradle/aurora-cradle-sharp.csproj index 2b41fe9..1e350d2 100644 --- a/AuroraCradle/aurora-cradle-sharp.csproj +++ b/AuroraCradle/aurora-cradle-sharp.csproj @@ -10,6 +10,7 @@ + From dc6776f70c8fac1d6e4e2de1da23aa820f3e9e43 Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Fri, 5 Mar 2021 20:49:49 -0500 Subject: [PATCH 10/10] Adding .vscode --- .gitignore | 1 - .vscode/launch.json | 27 +++++++++++++++++++++++++++ .vscode/tasks.json | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.gitignore b/.gitignore index 0626272..9feacfd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ project.lock.json nupkg/ # Visual Studio Code -.vscode # Rider .idea diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..14a9546 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/AuroraCradle/bin/Debug/netcoreapp3.1/aurora-cradle-sharp.dll", + "args": [], + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..736a20a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/AuroraCradle/aurora-cradle-sharp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/aurora-cradle-sharp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/aurora-cradle-sharp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +}