diff --git a/aurora-cradle-sharp/.gitignore b/aurora-cradle-sharp/.gitignore new file mode 100644 index 0000000..9feacfd --- /dev/null +++ b/aurora-cradle-sharp/.gitignore @@ -0,0 +1,36 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code + +# 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/aurora-cradle-sharp/.vscode/launch.json b/aurora-cradle-sharp/.vscode/launch.json new file mode 100644 index 0000000..14a9546 --- /dev/null +++ b/aurora-cradle-sharp/.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/aurora-cradle-sharp/.vscode/tasks.json b/aurora-cradle-sharp/.vscode/tasks.json new file mode 100644 index 0000000..736a20a --- /dev/null +++ b/aurora-cradle-sharp/.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" + } + ] +} diff --git a/aurora-cradle-sharp/AuroraCradle.test/AuroraSignal.test.csproj b/aurora-cradle-sharp/AuroraCradle.test/AuroraSignal.test.csproj new file mode 100644 index 0000000..8aa4944 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle.test/AuroraSignal.test.csproj @@ -0,0 +1,27 @@ + + + + net5.0 + + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/aurora-cradle-sharp/AuroraCradle.test/CursorList.test.cs b/aurora-cradle-sharp/AuroraCradle.test/CursorList.test.cs new file mode 100644 index 0000000..4a99d96 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle.test/CursorList.test.cs @@ -0,0 +1,163 @@ +using Xunit; +using Aurora.Services.Signal; +using Aurora.Cursor; +using System.Collections.Generic; +using System.Linq; + +namespace AuroraCradle.test +{ + public class CursorListTest + { + [Theory()] + [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() }); + 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) + .GetNextPage(); + + if (direction == Aurora.Cursor.SortDirection.Desc) + { + Assert.Collection(result.Result, + item => item.Name.Equals("asdf"), + item => item.Name.Equals("bsdf"), + item => item.Name.Equals("csdf")); + } + else + { + Assert.Collection(result.Result, + item => item.Name.Equals("csdf"), + item => item.Name.Equals("bsdf"), + item => item.Name.Equals("asdf")); + + } + } + + [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); + } + } + + [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, Aurora.Cursor.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/aurora-cradle-sharp/AuroraCradle/Src/Augments/Party.cs b/aurora-cradle-sharp/AuroraCradle/Src/Augments/Party.cs new file mode 100644 index 0000000..52c697f --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Augments/Party.cs @@ -0,0 +1,9 @@ +using Aurora.Cursor; + +namespace Aurora.Services.Signal +{ + public partial class Party : ICursorObject + { + } +} + diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Cursor/Cursor.cs b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/Cursor.cs new file mode 100644 index 0000000..9a60991 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/Cursor.cs @@ -0,0 +1,126 @@ +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.Key; + }; + } + + public CursorResult GetNextPage() + { + if (this._pageSize < 0) + { + throw new InvalidOperationException("Page Size must be greater than zero"); + } + 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) + 1; + } + + int adjustedSize = this._pageSize; + if (startIdx + this._pageSize > tmpList.Count) + { + adjustedSize = this._pageSize - ((startIdx + _pageSize) - tmpList.Count); + } + + + List> selection = new List>(); + if (adjustedSize != 0) + { + selection = tmpList.GetRange(startIdx, adjustedSize); + } + + return new CursorResult + { + 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) + }; + } + + public CursorResult GetPreviousPage() + { + throw new NotImplementedException(); + } + + public Cursor WithNextPageToken(string nextPageToken) + { + this._nextPageToken = nextPageToken; + return this; + } + + public Cursor WithPreviousPageToken(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 WithSort(string key, SortDirection direction) + { + this._sortDelgate = (item) => key; + this._direction = direction; + return this; + } + + public Cursor WithSize(int size) + { + this._pageSize = size; + return this; + } + } + +} \ No newline at end of file diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorList.cs b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorList.cs new file mode 100644 index 0000000..0dcbf04 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorList.cs @@ -0,0 +1,37 @@ +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 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) + { + throw new System.Exception("Failed to add item to cursor list"); + } + return this; + } + + + } +} \ No newline at end of file diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorObject.cs b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorObject.cs new file mode 100644 index 0000000..cca1779 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorResult.cs b/aurora-cradle-sharp/AuroraCradle/Src/Cursor/CursorResult.cs new file mode 100644 index 0000000..ab50c6a --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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/aurora-cradle-sharp/AuroraCradle/Src/Program.cs b/aurora-cradle-sharp/AuroraCradle/Src/Program.cs new file mode 100644 index 0000000..6ffeaba --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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 +{ + 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/aurora-cradle-sharp/AuroraCradle/Src/Protos/signal.proto b/aurora-cradle-sharp/AuroraCradle/Src/Protos/signal.proto new file mode 100644 index 0000000..078630d --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Protos/signal.proto @@ -0,0 +1,167 @@ +syntax = "proto3"; + +option csharp_namespace = "Aurora.Services.Signal"; + +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 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 id = 2; +} + +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 { + 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; +} diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/Events.cs b/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/Events.cs new file mode 100644 index 0000000..41e7034 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/Party.cs b/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/Party.cs new file mode 100644 index 0000000..c044cde --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/Party.cs @@ -0,0 +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) + { + 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) + { + 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) + { + 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) + { + 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) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/SignalService.cs b/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/SignalService.cs new file mode 100644 index 0000000..3561c59 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Services/Signal/SignalService.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Logging; +using Aurora.Cursor; + +namespace Aurora.Services.Signal +{ + public partial class SignalService : Signal.SignalBase + { + private readonly ILogger _logger; + + public SignalService(ILogger logger) + { + _logger = logger; + this._partyList = new CursorList(); + } + + } +} diff --git a/aurora-cradle-sharp/AuroraCradle/Src/Startup.cs b/aurora-cradle-sharp/AuroraCradle/Src/Startup.cs new file mode 100644 index 0000000..57b8520 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/Src/Startup.cs @@ -0,0 +1,50 @@ +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; +using Aurora.Services.Signal; + +namespace Aurora +{ + 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(); + services.AddGrpcReflection(); + } + + // 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(); + + 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/aurora-cradle-sharp/AuroraCradle/Src/Utils/HashUtil.cs b/aurora-cradle-sharp/AuroraCradle/Src/Utils/HashUtil.cs new file mode 100644 index 0000000..0644870 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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/aurora-cradle-sharp/AuroraCradle/appsettings.Development.json b/aurora-cradle-sharp/AuroraCradle/appsettings.Development.json new file mode 100644 index 0000000..fe20c40 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Grpc": "Information", + "Microsoft": "Information" + } + } +} diff --git a/aurora-cradle-sharp/AuroraCradle/appsettings.json b/aurora-cradle-sharp/AuroraCradle/appsettings.json new file mode 100644 index 0000000..df549a7 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/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/AuroraCradle/aurora-cradle-sharp.csproj b/aurora-cradle-sharp/AuroraCradle/aurora-cradle-sharp.csproj new file mode 100644 index 0000000..1e350d2 --- /dev/null +++ b/aurora-cradle-sharp/AuroraCradle/aurora-cradle-sharp.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/aurora-cradle-sharp/README.md b/aurora-cradle-sharp/README.md new file mode 100644 index 0000000..e230517 --- /dev/null +++ b/aurora-cradle-sharp/README.md @@ -0,0 +1,2 @@ +# aurora-cradle-sharp + diff --git a/aurora-cradle-sharp/workspace.code-workspace b/aurora-cradle-sharp/workspace.code-workspace new file mode 100644 index 0000000..1e373c0 --- /dev/null +++ b/aurora-cradle-sharp/workspace.code-workspace @@ -0,0 +1,15 @@ +{ + "folders": [ + { + "path": "." + } + ], +"settings": { + "files.exclude": { + "**/obj": true + }, + "dotnet-test-explorer.testProjectPath": "./AuroraCradle.test", + "editor.formatOnSave": true, + "editor.defaultFormatter": "ms-dotnettools.csharp" +} +}