Pārlūkot izejas kodu

Merge branch 'develop3.0' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0

CrazyIter 5 gadi atpakaļ
vecāks
revīzija
0c02d08058

+ 46 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksEndpointRouteBuilderExtensions.cs

@@ -0,0 +1,46 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.HealthCheck;
+using Microsoft.AspNetCore.Routing;
+
+namespace Microsoft.AspNetCore.Builder
+{
+    /// <summary>
+    /// Provides extension methods for <see cref="IEndpointRouteBuilder"/> to add gRPC service endpoints.
+    /// </summary>
+    public static class GrpcHealthChecksEndpointRouteBuilderExtensions
+    {
+        /// <summary>
+        /// Maps incoming requests to the gRPC health checks service.
+        /// This service can be queried to discover the health of the server.
+        /// </summary>
+        /// <param name="builder">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
+        /// <returns>An <see cref="GrpcServiceEndpointConventionBuilder"/> for endpoints associated with the service.</returns>
+        public static GrpcServiceEndpointConventionBuilder MapGrpcHealthChecksService(this IEndpointRouteBuilder builder)
+        {
+            if (builder == null)
+            {
+                throw new ArgumentNullException(nameof(builder));
+            }
+
+            return builder.MapGrpcService<HealthServiceImpl>();
+        }
+    }
+}

+ 56 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksPublisher.cs

@@ -0,0 +1,56 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Health.V1;
+using Grpc.HealthCheck;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace Grpc.AspNetCore.HealthChecks
+{
+    internal class GrpcHealthChecksPublisher : IHealthCheckPublisher
+    {
+        private readonly HealthServiceImpl _healthService;
+
+        public GrpcHealthChecksPublisher(HealthServiceImpl healthService)
+        {
+            _healthService = healthService;
+        }
+
+        public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
+        {
+            foreach (var entry in report.Entries)
+            {
+                var status = entry.Value.Status;
+
+                _healthService.SetStatus(entry.Key, ResolveStatus(status));
+            }
+
+            return Task.CompletedTask;
+        }
+
+        private static HealthCheckResponse.Types.ServingStatus ResolveStatus(HealthStatus status)
+        {
+            return status == HealthStatus.Unhealthy
+                ? HealthCheckResponse.Types.ServingStatus.NotServing
+                : HealthCheckResponse.Types.ServingStatus.Serving;
+        }
+    }
+
+}

+ 52 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksServiceExtensions.cs

@@ -0,0 +1,52 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.AspNetCore.HealthChecks;
+using Grpc.HealthCheck;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+    /// <summary>
+    /// Extension methods for the gRPC health checks services.
+    /// </summary>
+    public static class GrpcHealthChecksServiceExtensions
+    {
+        /// <summary>
+        /// Adds gRPC health check services to the specified <see cref="IServiceCollection" />.
+        /// </summary>
+        /// <param name="services">The <see cref="IServiceCollection"/> for adding services.</param>
+        /// <returns>An instance of <see cref="IHealthChecksBuilder"/> from which health checks can be registered.</returns>
+        public static IHealthChecksBuilder AddGrpcHealthChecks(this IServiceCollection services)
+        {
+            if (services == null)
+            {
+                throw new ArgumentNullException(nameof(services));
+            }
+
+            // HealthServiceImpl is designed to be a singleton
+            services.TryAddSingleton<HealthServiceImpl>();
+
+            services.TryAddEnumerable(ServiceDescriptor.Singleton<IHealthCheckPublisher, GrpcHealthChecksPublisher>());
+
+            return services.AddHealthChecks();
+        }
+    }
+}

+ 24 - 0
TEAMModelGrpc/Models/BlobSASDto.cs

@@ -0,0 +1,24 @@
+using ProtoBuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelGrpc.Models
+{
+    [ProtoContract]
+    public class BlobSASDto
+    {
+        /// <summary>
+        /// Blob的URL地址
+        /// </summary>
+        [ProtoMember(1)]
+        public string Url { get; set; }
+
+        /// <summary>
+        /// Blob的SAS签名
+        /// </summary>
+        [ProtoMember(2)]
+        public string SAS { get; set; }
+    }
+}

+ 24 - 0
TEAMModelGrpc/Protos/BlobSASService.proto

@@ -0,0 +1,24 @@
+syntax = "proto3";
+option csharp_namespace = "TMDGrpc.BlobSASService";
+option java_package = "TMDGrpc.BlobSASService";
+package math;
+
+
+service BlobSASService {
+   rpc GetContainerSasUri(Empty) returns(BlobSASDto);
+
+   rpc GetContainerSASRead(BlobSASDto) returns(BlobSASDto);
+
+}
+
+
+
+message Empty {
+}
+
+message BlobSASDto {
+   //Blob的URL地址
+   string Url = 1;
+   //Blob的SAS签名
+   string SAS = 2;
+}

+ 64 - 0
TEAMModelGrpc/Services/BlobSASService.cs

@@ -0,0 +1,64 @@
+using Google.Protobuf.WellKnownTypes;
+using Grpc.Core;
+using Grpc.Extension.Abstract;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelGrpc.Models;
+using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
+
+namespace TEAMModelGrpc.Services
+{
+    public class BlobSASService : IGrpcService
+    {
+
+        private readonly IAzureBlobDBRepository _azureBlobDBRepository;
+
+        public BlobSASService(IAzureBlobDBRepository azureBlobDBRepository)
+        {
+            _azureBlobDBRepository = azureBlobDBRepository;
+        }
+
+        public async Task<BlobSASDto> GetContainerSasUri(Empty empty, ServerCallContext context) {
+            (string, string) aaa = _azureBlobDBRepository.GetContainerSasUri();
+            BlobSASDto blobSASDto = new BlobSASDto();
+            blobSASDto.Url = aaa.Item1;
+            blobSASDto.SAS = aaa.Item2;
+            return blobSASDto;
+        }
+
+        public async Task<BlobSASDto> GetContainerSASRead(BlobSASDto blob, ServerCallContext context)
+        {
+            (string, string) a = BlobUrlString(blob.Url);
+            string ContainerName = a.Item1;
+            string BlobName = a.Item2;
+            bool flg = IsBlobName(BlobName);
+            if (flg)
+            {
+                string SAS = _azureBlobDBRepository.GetBlobSasUriRead(ContainerName, BlobName);
+                return new BlobSASDto { Url = SAS };
+            }
+            else throw new Exception();
+            //return responseBuilder.Error(false, ResponseCode.PARAMS_ERROR, "文件名错误").build();
+
+        }
+
+        private static (string, string) BlobUrlString(string sasUrl)
+        {
+            sasUrl = sasUrl.Substring(8);
+            string[] sasUrls = sasUrl.Split("/");
+            string ContainerName;
+            ContainerName = sasUrls[1].Clone().ToString();
+            string item = sasUrls[0] + "/" + sasUrls[1] + "/";
+            string blob = sasUrl.Replace(item, "");
+            return (ContainerName, blob);
+        }
+
+        public static bool IsBlobName(string BlobName)
+        {
+            return System.Text.RegularExpressions.Regex.IsMatch(BlobName,
+             @"(?!((^(con)$)|^(con)\\..*|(^(prn)$)|^(prn)\\..*|(^(aux)$)|^(aux)\\..*|(^(nul)$)|^(nul)\\..*|(^(com)[1-9]$)|^(com)[1-9]\\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\\..*)|^\\s+|.*\\s$)(^[^\\\\\\:\\<\\>\\*\\?\\\\\\""\\\\|]{1,255}$)");
+        }
+    }
+}

+ 13 - 1
TEAMModelGrpc/Startup.cs

@@ -23,6 +23,7 @@ using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
 using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
 using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
 using TEAMModelOS.SDK.Module.AzureTable.Implements;
 using TEAMModelOS.SDK.Module.AzureTable.Implements;
 using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
 using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
 
 
 namespace TEAMModelGrpc
 namespace TEAMModelGrpc
 {
 {
@@ -40,6 +41,17 @@ namespace TEAMModelGrpc
             services.AddGrpc();
             services.AddGrpc();
             //添加Grpc扩展
             //添加Grpc扩展
             services.AddGrpcExtensions(_conf);
             services.AddGrpcExtensions(_conf);
+            //Grpc健康检查
+            services.AddGrpcHealthChecks()
+               .AddAsyncCheck("", () =>
+               {
+                   var r = new Random();
+                   var result = r.Next() % 5 == 0
+                       ? HealthCheckResult.Unhealthy()
+                       : HealthCheckResult.Healthy();
+
+                   return Task.FromResult(result);
+               }, Array.Empty<string>());
 
 
             services.AddAuthorization(options =>
             services.AddAuthorization(options =>
             {
             {
@@ -101,7 +113,7 @@ namespace TEAMModelGrpc
             app.UseEndpoints(endpoints =>
             app.UseEndpoints(endpoints =>
             {
             {
                 endpoints.MapGrpcService<KnowledgeService>();
                 endpoints.MapGrpcService<KnowledgeService>();
-
+                endpoints.MapGrpcHealthChecksService();
                 endpoints.MapGet("/generateJwtToken", context =>
                 endpoints.MapGet("/generateJwtToken", context =>
                 {
                 {
                     return context.Response.WriteAsync(GenerateJwtToken(context.Request.Query["name"]));
                     return context.Response.WriteAsync(GenerateJwtToken(context.Request.Query["name"]));

+ 5 - 0
TEAMModelGrpc/TEAMModelGrpc.csproj

@@ -20,14 +20,19 @@
 
 
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
     <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
+    <PackageReference Include="Grpc.HealthCheck" Version="2.28.1" />
     <PackageReference Include="Grpc.Tools" Version="2.27.0">
     <PackageReference Include="Grpc.Tools" Version="2.27.0">
       <PrivateAssets>all</PrivateAssets>
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
     </PackageReference>
+    <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.3" />
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
     <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
     <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
     <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="GrpcHealthCheck\" />
+  </ItemGroup>
 </Project>
 </Project>

+ 35 - 0
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -4,6 +4,41 @@
         <name>TEAMModelGrpc</name>
         <name>TEAMModelGrpc</name>
     </assembly>
     </assembly>
     <members>
     <members>
+        <member name="T:Microsoft.AspNetCore.Builder.GrpcHealthChecksEndpointRouteBuilderExtensions">
+            <summary>
+            Provides extension methods for <see cref="T:Microsoft.AspNetCore.Routing.IEndpointRouteBuilder"/> to add gRPC service endpoints.
+            </summary>
+        </member>
+        <member name="M:Microsoft.AspNetCore.Builder.GrpcHealthChecksEndpointRouteBuilderExtensions.MapGrpcHealthChecksService(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder)">
+            <summary>
+            Maps incoming requests to the gRPC health checks service.
+            This service can be queried to discover the health of the server.
+            </summary>
+            <param name="builder">The <see cref="T:Microsoft.AspNetCore.Routing.IEndpointRouteBuilder"/> to add the route to.</param>
+            <returns>An <see cref="T:Microsoft.AspNetCore.Builder.GrpcServiceEndpointConventionBuilder"/> for endpoints associated with the service.</returns>
+        </member>
+        <member name="T:Microsoft.Extensions.DependencyInjection.GrpcHealthChecksServiceExtensions">
+            <summary>
+            Extension methods for the gRPC health checks services.
+            </summary>
+        </member>
+        <member name="M:Microsoft.Extensions.DependencyInjection.GrpcHealthChecksServiceExtensions.AddGrpcHealthChecks(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
+            <summary>
+            Adds gRPC health check services to the specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
+            </summary>
+            <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection"/> for adding services.</param>
+            <returns>An instance of <see cref="T:Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder"/> from which health checks can be registered.</returns>
+        </member>
+        <member name="P:TEAMModelGrpc.Models.BlobSASDto.Url">
+            <summary>
+            Blob的URL地址
+            </summary>
+        </member>
+        <member name="P:TEAMModelGrpc.Models.BlobSASDto.SAS">
+            <summary>
+            Blob的SAS签名
+            </summary>
+        </member>
         <member name="T:TEAMModelGrpc.Models.Dict">
         <member name="T:TEAMModelGrpc.Models.Dict">
             <summary>
             <summary>
             请求参数Dict
             请求参数Dict

+ 1 - 1
TEAMModelGrpc/appsettings.Development.json

@@ -36,7 +36,7 @@
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn"
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn"
     },
     },
     "Blob": {
     "Blob": {
-      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn",
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn", //"DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn",
       "Container": "teammodelos"
       "Container": "teammodelos"
     },
     },
     "CosmosDB": {
     "CosmosDB": {

+ 21 - 5
TEAMModelOS/Controllers/Learn/HomeWorkController.cs

@@ -47,6 +47,8 @@ namespace TEAMModelOS.Controllers.Learn
             }
             }
             bool flg = false; 
             bool flg = false; 
 
 
+
+            //新增
             if (string.IsNullOrEmpty(request.@params.id)) {
             if (string.IsNullOrEmpty(request.@params.id)) {
 
 
                 request.@params.id = Guid.NewGuid().ToString();
                 request.@params.id = Guid.NewGuid().ToString();
@@ -54,10 +56,13 @@ namespace TEAMModelOS.Controllers.Learn
                 flg = true;
                 flg = true;
             }
             }
 
 
+            //重新发布
+
 
 
             HomeWork homeWork = await _cosmos.SaveOrUpdate<HomeWork>(request.@params);
             HomeWork homeWork = await _cosmos.SaveOrUpdate<HomeWork>(request.@params);
 
 
-            if (flg) {
+            if (flg)
+            {
                 //根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
                 //根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
                 List<Target> targets = request.@params.target;
                 List<Target> targets = request.@params.target;
                 List<ClassroomStudent> Classrooms = new List<ClassroomStudent>();
                 List<ClassroomStudent> Classrooms = new List<ClassroomStudent>();
@@ -66,11 +71,12 @@ namespace TEAMModelOS.Controllers.Learn
                 {
                 {
                     List<ClassroomStudent> classroom = await _cosmos.FindByDict<ClassroomStudent>(new Dictionary<string, object> { { "id", target.classroomCode }, { "scopeCode", target.scopeCode } });
                     List<ClassroomStudent> classroom = await _cosmos.FindByDict<ClassroomStudent>(new Dictionary<string, object> { { "id", target.classroomCode }, { "scopeCode", target.scopeCode } });
 
 
-                    if (classroom.IsNotEmpty()) {
+                    if (classroom.IsNotEmpty())
+                    {
                         foreach (string studentid in classroom[0].studentId)
                         foreach (string studentid in classroom[0].studentId)
                         {
                         {
                             HomeWorkStudent homeWorkStudent = new HomeWorkStudent();
                             HomeWorkStudent homeWorkStudent = new HomeWorkStudent();
-                            homeWorkStudent.id = Guid.NewGuid().ToString();
+                            homeWorkStudent.id = studentid;
                             homeWorkStudent.homeWorkId = request.@params.id;
                             homeWorkStudent.homeWorkId = request.@params.id;
                             homeWorkStudent.studentId = studentid;
                             homeWorkStudent.studentId = studentid;
                             homeWorkStudent.classroom.code = target.classroomCode;
                             homeWorkStudent.classroom.code = target.classroomCode;
@@ -78,7 +84,7 @@ namespace TEAMModelOS.Controllers.Learn
                             homeWorkStudents.Add(homeWorkStudent);
                             homeWorkStudents.Add(homeWorkStudent);
                         }
                         }
                     }
                     }
-                    
+
                 }
                 }
                 if (homeWorkStudents.IsNotEmpty())
                 if (homeWorkStudents.IsNotEmpty())
                 {
                 {
@@ -95,10 +101,20 @@ namespace TEAMModelOS.Controllers.Learn
                     }
                     }
                     await _cosmos.SaveOrUpdateAll<HomeWorkStudent>(homeWorkStudents);
                     await _cosmos.SaveOrUpdateAll<HomeWorkStudent>(homeWorkStudents);
                 }
                 }
+            }
+            //else {
+            //    List<Target> targets = request.@params.target;
+            //    foreach (Target target in targets) { 
+            //        List<HomeWorkStudent> classroom = await _cosmos.FindByDict<HomeWorkStudent>(new Dictionary<string, object> { { "id", target.classroomCode }, { "scopeCode", target.scopeCode } });
 
 
 
 
 
 
-            }
+            //    }
+
+
+
+
+            //}
            
            
 
 
             return builder.Data(homeWork).build();
             return builder.Data(homeWork).build();