Просмотр исходного кода

統測活動行程進行狀況更新架構

jeff 10 месяцев назад
Родитель
Сommit
bff832aa87

+ 128 - 1
TEAMModelOS.Function/IESServiceBusTrigger.cs

@@ -2055,7 +2055,6 @@ namespace TEAMModelOS.Function
             var json = JsonDocument.Parse(message.Body);
             var json = JsonDocument.Parse(message.Body);
             try
             try
             {
             {
-
                 json.RootElement.TryGetProperty("id", out JsonElement id);
                 json.RootElement.TryGetProperty("id", out JsonElement id);
                 json.RootElement.TryGetProperty("progress", out JsonElement progress);
                 json.RootElement.TryGetProperty("progress", out JsonElement progress);
                 json.RootElement.TryGetProperty("code", out JsonElement code);
                 json.RootElement.TryGetProperty("code", out JsonElement code);
@@ -2078,6 +2077,134 @@ namespace TEAMModelOS.Function
             }
             }
 
 
         }
         }
+        /// <summary>
+        /// 統測活動行程進行狀況更新
+        /// </summary>
+        /// <param name="message"></param>
+        /// <param name="messageActions"></param>
+        /// <returns></returns>
+        [Function("JointEventSchedule")]
+        public async Task JointEventFunc(
+            [ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "jointevent-schedule", Connection = "Azure:ServiceBus:ConnectionString")]
+            ServiceBusReceivedMessage message,
+            ServiceBusMessageActions messageActions)
+        {
+            _logger.LogInformation("Message ID: {id}", message.MessageId);
+            _logger.LogInformation("Message Body: {body}", message.Body);
+            _logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
+            var jsonMsg = JsonDocument.Parse(message.Body).RootElement;
+            try
+            {
+                jsonMsg.TryGetProperty("jointEventId", out JsonElement jointEventId);
+                jsonMsg.TryGetProperty("jointScheduleId", out JsonElement jointScheduleId);
+                jsonMsg.TryGetProperty("progress", out JsonElement progress);
+
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                string PartitionKey = string.Format("{0}{1}{2}{3}{4}{5}{6}", "JointEvent", "-", $"{jointEventId}", "-", "schedule", "-", $"{progress}"); //主key: JointEvent-{jointEventId}-schedule-{progress}  RowKey: {jointScheduleId}
+                List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", $"{jointScheduleId}" }, { "PartitionKey", PartitionKey } });
+
+                bool updFlg = false;
+                string code = "JointEvent";
+                var client = _azureCosmos.GetCosmosClient();
+                
+                JointEvent jointEvent = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<JointEvent>(jointEventId.ToString(), new PartitionKey($"{code}"));
+                if (jointEvent != null)
+                {
+                    JointEvent.JointEventSchedule jointEventSchedule = jointEvent.schedule.Where(s => s.id.Equals($"{jointScheduleId}")).FirstOrDefault();
+                    if (jointEventSchedule != null)
+                    {
+                        //資料處理
+                        if (!jointEventSchedule.progress.Equals($"{progress}"))
+                        {
+                            jointEventSchedule.progress = $"{progress}";
+                            updFlg = true;
+                        }
+                        if (updFlg)
+                        {
+                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(jointEvent, jointEvent.id);
+                        }
+                        //訊息處理
+                        switch (jointEventSchedule.progress)
+                        {
+                            case "pending":
+                                var msg = new ServiceBusMessage(new { jointEventId = $"{jointEventId}", jointScheduleId = $"{jointScheduleId}", progress = "going" }.ToJsonString());
+                                msg.ApplicationProperties.Add("name", "JointEventSchedule");
+                                if (records.Count > 0)
+                                {
+                                    try
+                                    {
+                                        await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), records[0].sequenceNumber);
+                                    }
+                                    catch (Exception)
+                                    {
+                                    }
+                                    long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), msg, DateTimeOffset.FromUnixTimeMilliseconds(jointEventSchedule.startTime));
+                                    records[0].sequenceNumber = start;
+                                    await table.SaveOrUpdate<ChangeRecord>(records[0]);
+                                }
+                                else
+                                {
+                                    long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), msg, DateTimeOffset.FromUnixTimeMilliseconds(jointEventSchedule.startTime));
+                                    ChangeRecord changeRecord = new ChangeRecord
+                                    {
+                                        RowKey = jointEventSchedule.id,
+                                        PartitionKey = PartitionKey,
+                                        sequenceNumber = start,
+                                        msgId = message.MessageId
+                                    };
+                                    await table.Save<ChangeRecord>(changeRecord);
+                                }
+                                break;
+                            case "going":
+                                //刪除pending訊息
+                                string pkey = string.Format("{0}{1}{2}{3}{4}{5}{6}", "JointEvent", "-", $"{jointEventId}", "-", "schedule", "-", "pending");
+                                await table.DeleteSingle<ChangeRecord>(pkey, jointEventSchedule.id);
+                                //發送finish訊息
+                                var messageEnd = new ServiceBusMessage(new { jointEventId = $"{jointEventId}", jointScheduleId = $"{jointScheduleId}", progress = "finish" }.ToJsonString());
+                                messageEnd.ApplicationProperties.Add("name", "JointEventSchedule");
+                                if (records.Count > 0)
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(jointEventSchedule.endTime));
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), records[0].sequenceNumber);
+                                    records[0].sequenceNumber = end;
+                                    await table.SaveOrUpdate<ChangeRecord>(records[0]);
+                                }
+                                else
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(jointEventSchedule.endTime));
+                                    ChangeRecord changeRecord = new ChangeRecord
+                                    {
+                                        RowKey = jointEventSchedule.id,
+                                        PartitionKey = PartitionKey,
+                                        sequenceNumber = end,
+                                        msgId = messageEnd.MessageId
+                                    };
+                                    await table.Save<ChangeRecord>(changeRecord);
+                                }
+                                break;
+                            case "finish":
+                                string pk = string.Format("{0}{1}{2}{3}{4}{5}{6}", "JointEvent", "-", $"{jointEventId}", "-", "schedule", "-", "going");
+                                await table.DeleteSingle<ChangeRecord>(pk, jointEventSchedule.id);
+                                break;
+                        }
+                    }
+                }
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,JointEventScheduleBus()-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.StatusCode}\n{jsonMsg.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,JointEventScheduleBus()\n{ex.Message}\n{ex.StackTrace}\n\n{jsonMsg.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+            }
+            finally
+            {  // Complete the message
+                await messageActions.CompleteMessageAsync(message);
+            }
+
+        }
+
         private async Task RefreshBlob(string name, string u)
         private async Task RefreshBlob(string name, string u)
         {
         {
             long statr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             long statr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

+ 19 - 0
TEAMModelOS/Controllers/Teacher/JointEventController.cs

@@ -20,6 +20,7 @@ using System;
 using static TEAMModelOS.SDK.Models.JointEvent;
 using static TEAMModelOS.SDK.Models.JointEvent;
 using System.Linq;
 using System.Linq;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service;
+using Azure.Messaging.ServiceBus;
 
 
 namespace TEAMModelOS.Controllers.Common
 namespace TEAMModelOS.Controllers.Common
 {
 {
@@ -280,6 +281,7 @@ namespace TEAMModelOS.Controllers.Common
                 if (string.IsNullOrWhiteSpace(jointEventId)) return BadRequest();
                 if (string.IsNullOrWhiteSpace(jointEventId)) return BadRequest();
                 List<JointEventSchedule> schedules = (request.TryGetProperty("schedules", out JsonElement _schedules)) ? _schedules.ToObject<List<JointEventSchedule>>() : new List<JointEventSchedule>();
                 List<JointEventSchedule> schedules = (request.TryGetProperty("schedules", out JsonElement _schedules)) ? _schedules.ToObject<List<JointEventSchedule>>() : new List<JointEventSchedule>();
                 if (schedules.Count.Equals(0)) return BadRequest();
                 if (schedules.Count.Equals(0)) return BadRequest();
+                var sbm = new List<ServiceBusMessage>(); //ServiceBus訊息列表
 
 
                 //取得活動本體
                 //取得活動本體
                 JointEvent jointEvent = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<JointEvent>(jointEventId, new PartitionKey("JointEvent"));
                 JointEvent jointEvent = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<JointEvent>(jointEventId, new PartitionKey("JointEvent"));
@@ -317,6 +319,8 @@ namespace TEAMModelOS.Controllers.Common
                     jointEventSchedule.type = schedule.type;
                     jointEventSchedule.type = schedule.type;
                     jointEventSchedule.examType = (schedule.type.Equals("join")) ? null : schedule.examType;
                     jointEventSchedule.examType = (schedule.type.Equals("join")) ? null : schedule.examType;
                     jointEventSchedule.examOverwrite = schedule.examOverwrite;
                     jointEventSchedule.examOverwrite = schedule.examOverwrite;
+                    long startTimeOld = jointEventSchedule.startTime;
+                    long endTimeOld = jointEventSchedule.endTime;
                     jointEventSchedule.startTime = schedule.startTime;
                     jointEventSchedule.startTime = schedule.startTime;
                     jointEventSchedule.endTime = schedule.endTime;
                     jointEventSchedule.endTime = schedule.endTime;
                     jointEventSchedule.progress = (schedule.startTime <= now && now <= schedule.endTime) ? "going" : (now < schedule.startTime) ? "pending" : "finish";
                     jointEventSchedule.progress = (schedule.startTime <= now && now <= schedule.endTime) ? "going" : (now < schedule.startTime) ? "pending" : "finish";
@@ -328,6 +332,14 @@ namespace TEAMModelOS.Controllers.Common
                     {
                     {
                         jointEvent.schedule.Add(jointEventSchedule);
                         jointEvent.schedule.Add(jointEventSchedule);
                     }
                     }
+                    //製作Schedule progress更新訊息(active-task)
+                    bool sendScheduleMsg = (!startTimeOld.Equals(jointEventSchedule.startTime) || endTimeOld.Equals(jointEventSchedule.endTime) ) ? true : false; //是否發送變更Schedule.progress訊息
+                    if(sendScheduleMsg)
+                    {
+                        var msg = new ServiceBusMessage(new { jointEventId = $"{jointEvent.id}", jointScheduleId = $"{jointEventSchedule.id}", progress = jointEventSchedule.progress }.ToJsonString());
+                        msg.ApplicationProperties.Add("name", "JointEventSchedule");
+                        sbm.Add(msg);
+                    }
                 }
                 }
                 //排序
                 //排序
                 jointEvent.schedule = jointEvent.schedule.OrderBy(s => s.orderby).ToList();
                 jointEvent.schedule = jointEvent.schedule.OrderBy(s => s.orderby).ToList();
@@ -340,6 +352,13 @@ namespace TEAMModelOS.Controllers.Common
 
 
                 //DB更新:JointEvent
                 //DB更新:JointEvent
                 await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<JointEvent>(jointEvent, jointEvent.id, new PartitionKey("JointEvent"));
                 await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<JointEvent>(jointEvent, jointEvent.id, new PartitionKey("JointEvent"));
+
+                //批量發送Schedule progress消息
+                if(sbm.Count > 0)
+                {
+                    var s = await _serviceBus.GetServiceBusClient().SendBatchMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), sbm);
+                }
+
                 return Ok(new { errCode, err, jointEvent });
                 return Ok(new { errCode, err, jointEvent });
             }
             }
             catch (Exception e)
             catch (Exception e)