| @@ -1,7 +1,7 @@ | |||
| using IdentityProvider.Protos.AuthService; | |||
| //using IdentityProvider.Protos.AuthService; | |||
| namespace IdentityProvider.Services | |||
| { | |||
| public class AuthService : AuthorizationService.AuthorizationServiceBase | |||
| public class AuthService | |||
| { | |||
| private readonly ILogger<AuthService> _logger; | |||
| public AuthService(ILogger<AuthService> logger) | |||
| @@ -7,8 +7,23 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <None Remove="Protos\search.proto" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Google.Protobuf" Version="3.21.4" /> | |||
| <PackageReference Include="Grpc.Net.Client" Version="2.47.0" /> | |||
| <PackageReference Include="Grpc.Net.Client.Web" Version="2.47.0" /> | |||
| <PackageReference Include="Grpc.Tools" Version="2.47.0"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.7" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.7" PrivateAssets="all" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Protos\search.proto" GrpcServices="Client" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,4 +1,7 @@ | |||
| @page "/" | |||
| @using Grpc.Net.Client | |||
| @using Grpc.Net.Client.Web | |||
| @using SpotifyService.Protos | |||
| @inject NavigationManager NavigationManager | |||
| <PageTitle>Index</PageTitle> | |||
| @@ -15,4 +18,17 @@ Dobrodošli u našu NemAn aplikaciju. | |||
| NavigationManager.NavigateTo( | |||
| "https://accounts.spotify.com/en/authorize?client_id=83e1d09876b049c4bb1953185a4b3bfb&redirect_uri=https%3A%2F%2Flocalhost%3A7229%2F&response_type=code&scope=user-read-currently-playing%20user-read-email%20user-library-modify%20user-top-read%0A%0A%0A&show_dialog=true"); | |||
| } | |||
| private async Task Grpc() | |||
| { | |||
| var channel = GrpcChannel.ForAddress("https://localhost:7251", new GrpcChannelOptions | |||
| { | |||
| HttpHandler = new GrpcWebHandler(new HttpClientHandler()) | |||
| }); | |||
| var client = new Search.SearchClient(channel); | |||
| var response = await client.SearchForItemAsync(new SearchForItemRequest { Query = "venom", Type = "track", Limit = 5, Offset = 0, IncludeExternal = "audio"}); | |||
| } | |||
| } | |||
| @@ -1,3 +1,4 @@ | |||
| using Microsoft.AspNetCore.Components.Web; | |||
| using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | |||
| using NemAnBlazor; | |||
| @@ -8,5 +9,6 @@ builder.RootComponents.Add<HeadOutlet>("head::after"); | |||
| builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | |||
| await builder.Build().RunAsync(); | |||
| @@ -0,0 +1,3 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "SpotifyService.Protos"; | |||
| @@ -0,0 +1,74 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "SpotifyService.Protos"; | |||
| package search; | |||
| service Search{ | |||
| rpc SearchForItem(SearchForItemRequest) returns (SearchForItemResponse); | |||
| } | |||
| message SearchForItemRequest{ | |||
| string query = 1; | |||
| string type = 2; | |||
| string include_external = 3; | |||
| int32 limit = 4; | |||
| int32 offset = 5; | |||
| } | |||
| message SearchForItemResponse{ | |||
| message Tracks { | |||
| string href = 1; | |||
| repeated Items items = 2; | |||
| } | |||
| Tracks tracks = 1; | |||
| message Items{ | |||
| Album album = 1; | |||
| repeated Artists artists = 2; | |||
| int32 duration_ms = 3; | |||
| External_urls1 external_urls = 4; | |||
| string href = 5; | |||
| string id = 6; | |||
| string name = 7; | |||
| int32 popularity = 8; | |||
| int32 track_number = 9; | |||
| string type = 10; | |||
| string uri = 11; | |||
| } | |||
| } | |||
| message Images { | |||
| uint32 height = 1; | |||
| string url = 2; | |||
| uint32 width = 3; | |||
| } | |||
| message Album { | |||
| string href = 1; | |||
| string id = 2; | |||
| repeated Images images = 3; | |||
| string name = 4; | |||
| string release_date = 5; | |||
| uint32 total_tracks = 6; | |||
| string type = 7; | |||
| string uri = 8; | |||
| } | |||
| message External_urls { | |||
| string spotify = 1; | |||
| } | |||
| message Artists { | |||
| External_urls external_urls = 1; | |||
| string href = 2; | |||
| string id = 3; | |||
| string name = 4; | |||
| string type = 5; | |||
| string uri = 6; | |||
| } | |||
| message External_urls1 { | |||
| string spotify = 1; | |||
| } | |||
| @@ -0,0 +1,127 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Globalization; | |||
| using System.Text.Json.Serialization; | |||
| namespace SpotifyService.Contracts | |||
| { | |||
| public partial class SearchContracts | |||
| { | |||
| [JsonPropertyName("tracks")] | |||
| public Tracks? Tracks { get; set; } | |||
| } | |||
| public partial class Tracks | |||
| { | |||
| [JsonPropertyName("href")] | |||
| public Uri Href { get; set; } | |||
| [JsonPropertyName("items")] | |||
| public Item[]? Items { get; set; } | |||
| } | |||
| public partial class Item | |||
| { | |||
| [JsonPropertyName("album")] | |||
| public Album Album { get; set; } | |||
| [JsonPropertyName("artists")] | |||
| public Artist[] Artists { get; set; } | |||
| [JsonPropertyName("duration_ms")] | |||
| public long DurationMs { get; set; } | |||
| [JsonPropertyName("external_urls")] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [JsonPropertyName("href")] | |||
| public Uri Href { get; set; } | |||
| [JsonPropertyName("id")] | |||
| public string Id { get; set; } | |||
| [JsonPropertyName("name")] | |||
| public string Name { get; set; } | |||
| [JsonPropertyName("popularity")] | |||
| public long Popularity { get; set; } | |||
| [JsonPropertyName("track_number")] | |||
| public long TrackNumber { get; set; } | |||
| [JsonPropertyName("type")] | |||
| public string Type { get; set; } | |||
| [JsonPropertyName("uri")] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class Album | |||
| { | |||
| [JsonPropertyName("href")] | |||
| public Uri Href { get; set; } | |||
| [JsonPropertyName("id")] | |||
| public string Id { get; set; } | |||
| [JsonPropertyName("images")] | |||
| public Image[] Images { get; set; } | |||
| [JsonPropertyName("name")] | |||
| public string Name { get; set; } | |||
| [JsonPropertyName("release_date")] | |||
| public DateTimeOffset ReleaseDate { get; set; } | |||
| [JsonPropertyName("total_tracks")] | |||
| public long TotalTracks { get; set; } | |||
| [JsonPropertyName("type")] | |||
| public string Type { get; set; } | |||
| [JsonPropertyName("uri")] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class Image | |||
| { | |||
| [JsonPropertyName("height")] | |||
| public long Height { get; set; } | |||
| [JsonPropertyName("url")] | |||
| public Uri Url { get; set; } | |||
| [JsonPropertyName("width")] | |||
| public long Width { get; set; } | |||
| } | |||
| public partial class Artist | |||
| { | |||
| [JsonPropertyName("external_urls")] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [JsonPropertyName("href")] | |||
| public Uri Href { get; set; } | |||
| [JsonPropertyName("id")] | |||
| public string Id { get; set; } | |||
| [JsonPropertyName("name")] | |||
| public string Name { get; set; } | |||
| [JsonPropertyName("type")] | |||
| public string Type { get; set; } | |||
| [JsonPropertyName("uri")] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class ExternalUrls | |||
| { | |||
| [JsonPropertyName("spotify")] | |||
| public Uri Spotify { get; set; } | |||
| } | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| using gRPCServer.Services; | |||
| using Grpc.Net.Client; | |||
| using SpotifyService.Services; | |||
| var builder = WebApplication.CreateBuilder(args); | |||
| @@ -8,10 +9,29 @@ var builder = WebApplication.CreateBuilder(args); | |||
| // Add services to the container. | |||
| builder.Services.AddGrpc(); | |||
| builder.Services.AddHttpClient(); | |||
| builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder => | |||
| { | |||
| builder.AllowAnyOrigin() | |||
| .AllowAnyMethod() | |||
| .AllowAnyHeader() | |||
| .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding"); | |||
| })); | |||
| var app = builder.Build(); | |||
| app.UseRouting(); | |||
| app.UseCors(); | |||
| // Configure the HTTP request pipeline. | |||
| app.MapGrpcService<GreeterService>(); | |||
| 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"); | |||
| app.MapGrpcService<SearchService>(); | |||
| app.UseGrpcWeb(); | |||
| app.UseEndpoints(endpoints => | |||
| { | |||
| endpoints.MapGrpcService<SearchService>().EnableGrpcWeb().RequireCors("AllowAll"); | |||
| }); | |||
| app.Run(); | |||
| @@ -0,0 +1,3 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "SpotifyService.Protos"; | |||
| @@ -1,21 +0,0 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "gRPCServer"; | |||
| package greet; | |||
| // The greeting service definition. | |||
| service Greeter { | |||
| // Sends a greeting | |||
| rpc SayHello (HelloRequest) returns (HelloReply); | |||
| } | |||
| // The request message containing the user's name. | |||
| message HelloRequest { | |||
| string name = 1; | |||
| } | |||
| // The response message containing the greetings. | |||
| message HelloReply { | |||
| string message = 1; | |||
| } | |||
| @@ -0,0 +1,74 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "SpotifyService.Protos"; | |||
| package search; | |||
| service Search{ | |||
| rpc SearchForItem(SearchForItemRequest) returns (SearchForItemResponse); | |||
| } | |||
| message SearchForItemRequest{ | |||
| string query = 1; | |||
| string type = 2; | |||
| string include_external = 3; | |||
| int32 limit = 4; | |||
| int32 offset = 5; | |||
| } | |||
| message SearchForItemResponse{ | |||
| message Tracks { | |||
| string href = 1; | |||
| repeated Items items = 2; | |||
| } | |||
| Tracks tracks = 1; | |||
| message Items{ | |||
| Album album = 1; | |||
| repeated Artists artists = 2; | |||
| int32 duration_ms = 3; | |||
| External_urls1 external_urls = 4; | |||
| string href = 5; | |||
| string id = 6; | |||
| string name = 7; | |||
| int32 popularity = 8; | |||
| int32 track_number = 9; | |||
| string type = 10; | |||
| string uri = 11; | |||
| } | |||
| } | |||
| message Images { | |||
| uint32 height = 1; | |||
| string url = 2; | |||
| uint32 width = 3; | |||
| } | |||
| message Album { | |||
| string href = 1; | |||
| string id = 2; | |||
| repeated Images images = 3; | |||
| string name = 4; | |||
| string release_date = 5; | |||
| uint32 total_tracks = 6; | |||
| string type = 7; | |||
| string uri = 8; | |||
| } | |||
| message External_urls { | |||
| string spotify = 1; | |||
| } | |||
| message Artists { | |||
| External_urls external_urls = 1; | |||
| string href = 2; | |||
| string id = 3; | |||
| string name = 4; | |||
| string type = 5; | |||
| string uri = 6; | |||
| } | |||
| message External_urls1 { | |||
| string spotify = 1; | |||
| } | |||
| @@ -1,22 +0,0 @@ | |||
| using Grpc.Core; | |||
| using gRPCServer; | |||
| namespace gRPCServer.Services | |||
| { | |||
| public class GreeterService : Greeter.GreeterBase | |||
| { | |||
| private readonly ILogger<GreeterService> _logger; | |||
| public GreeterService(ILogger<GreeterService> logger) | |||
| { | |||
| _logger = logger; | |||
| } | |||
| public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) | |||
| { | |||
| return Task.FromResult(new HelloReply | |||
| { | |||
| Message = "Hello " + request.Name | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| using SpotifyService.Protos; | |||
| using Grpc.Core; | |||
| using System.Text.Json; | |||
| using SpotifyService.Contracts; | |||
| namespace SpotifyService.Services | |||
| { | |||
| public class SearchService : Search.SearchBase | |||
| { | |||
| private readonly IHttpClientFactory _httpClientFactory; | |||
| public SearchService(IHttpClientFactory httpClientFactory) | |||
| { | |||
| _httpClientFactory = httpClientFactory; | |||
| } | |||
| public override async Task<SearchForItemResponse> SearchForItem(SearchForItemRequest request, ServerCallContext context) | |||
| { | |||
| var httpClient = _httpClientFactory.CreateClient(); | |||
| var responseText = await httpClient.GetStringAsync($"https://api.spotify.com/v1/search?q={request.Query}&type={request.Type}"); | |||
| var tracks = JsonSerializer.Deserialize<SearchContracts>(responseText); | |||
| return new SearchForItemResponse | |||
| { | |||
| Tracks = tracks!.Tracks.Items | |||
| }; | |||
| //return null; | |||
| } | |||
| } | |||
| } | |||
| @@ -7,11 +7,18 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Google.Protobuf" Version="3.21.4" /> | |||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||
| <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> | |||
| <PackageReference Include="Grpc.Net.Client" Version="2.47.0" /> | |||
| <PackageReference Include="Grpc.Tools" Version="2.47.0"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Protos\search.proto" GrpcServices="Server"></Protobuf> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -8,7 +8,7 @@ | |||
| "AllowedHosts": "*", | |||
| "Kestrel": { | |||
| "EndpointDefaults": { | |||
| "Protocols": "Http2" | |||
| "Protocols": "Http1AndHttp2" | |||
| } | |||
| } | |||
| } | |||