/// <summary> /// Process recieved message. /// </summary> /// <param name="context">Dialog context.</param> /// <param name="result">Awaitable string.</param> /// <returns>Task.</returns> private async Task ProcessRequest(IDialogContext context, IAwaitable <string> result) { var activity = context.Activity as Activity; var message = activity.Text?.Trim(); JObject tenant = context.Activity.ChannelData as JObject; string tenantId = tenant["tenant"].SelectToken("id").ToString(); string jSessionId = string.Empty; string personNumber = string.Empty; if (context.UserData.TryGetValue(context.Activity.From.Id, out this.response)) { jSessionId = this.response.JsessionID; personNumber = this.response.PersonNumber; } AppInsightsLogger.CustomEventTrace("ViewTimeOffRequestsDialog", new Dictionary <string, string>() { { "TenantId", tenantId }, { "User", context.Activity.From.Id }, { "methodName", "ProcessRequest" }, { "Command", message } }); if (message.ToLowerInvariant().Contains(Constants.ShowAllTimeOff.ToLowerInvariant())) { await this.ProcessShowAllTimeoff(context, tenantId, jSessionId, personNumber, message); } context.Done(default(string)); }
private static bool PublishEvent(APITask task, string taskBody, AppInsightsLogger appInsightsLogger) { string event_grid_topic_uri = Environment.GetEnvironmentVariable(EVENT_GRID_TOPIC_URI_VARIABLE_NAME, EnvironmentVariableTarget.Process); string event_grid_key = Environment.GetEnvironmentVariable(EVENT_GRID_KEY_VARIABLE_NAME, EnvironmentVariableTarget.Process); var ev = new EventGridEvent() { Id = task.TaskId, EventType = "task", Data = taskBody, EventTime = DateTime.Parse(task.Timestamp), Subject = task.Endpoint, DataVersion = "1.0" }; string topicHostname = new Uri(event_grid_topic_uri).Host; TopicCredentials topicCredentials = new TopicCredentials(event_grid_key); EventGridClient client = new EventGridClient(topicCredentials); try { client.PublishEventsAsync(topicHostname, new List <EventGridEvent>() { ev }).GetAwaiter().GetResult(); } catch (Exception ex) { appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId); return(false); } return(true); }
public void Test_Telemetry_LogErrorExceptionWithObject() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Error); // Act logger.LogError(new Exception("test"), new Test { PropA = "propA", PropB = 1, PropC = true, PropD = new SubItem { PropE = "propE", PropF = new List <int> { 1, 2, 3 } } }); logger.Flush(); }); }
public static async Task ServiceBusQueueProcessorAsync( [ServiceBusTrigger("%SERVICE_BUS_QUEUE%")] Message message, MessageReceiver messageReceiver, ILogger logger) { var timestamp = DateTime.UtcNow; var queueName = Environment.GetEnvironmentVariable("SERVICE_BUS_QUEUE", EnvironmentVariableTarget.Process); logger.LogTrace($@"[{message.UserProperties[@"TaskId"]}]: Message received at {timestamp}: {JObject.FromObject(message)}"); AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME + ": " + queueName, LOGGING_SERVICE_VERSION); var enqueuedTime = message.ScheduledEnqueueTimeUtc; var elapsedTimeMs = (timestamp - enqueuedTime).TotalMilliseconds; var taskId = message.UserProperties["TaskId"].ToString(); var backendUri = message.UserProperties["Uri"].ToString(); var messageBody = Encoding.UTF8.GetString(message.Body); try { appInsightsLogger.LogInformation($"Sending request to {backendUri} for taskId {taskId} from queue {queueName}. Queued for {elapsedTimeMs/60} seconds.", backendUri, taskId); var client = new HttpClient(); client.DefaultRequestHeaders.Add("taskId", taskId); var httpContent = new StringContent(messageBody, Encoding.UTF8, "application/json"); var res = await client.PostAsync(backendUri, httpContent); if (res.StatusCode == (System.Net.HttpStatusCode) 429) // Special return value indicating that the service is busy. { var retryDelay = int.Parse(Environment.GetEnvironmentVariable(QUEUE_RETRY_DELAY_MS_VARIABLE_NAME, EnvironmentVariableTarget.Process)); appInsightsLogger.LogInformation($"Service is busy. Will try again in {retryDelay/1000} seconds.", backendUri, taskId); await UpdateTaskStatus(taskId, backendUri, messageBody, $"Awaiting service availability. Queued for {elapsedTimeMs/60} seconds.", "created", appInsightsLogger); // Artifical delay is needed since the ServiceBusTrigger will retry immediately. await Task.Delay(retryDelay); await messageReceiver.AbandonAsync(message.SystemProperties.LockToken); throw new ApplicationException($"Service is busy. Will try again in {retryDelay/1000} seconds."); } else if (!res.IsSuccessStatusCode) { await messageReceiver.CompleteAsync(message.SystemProperties.LockToken); //Need to complete even though we have failure. This removes it from the queue to avoid an infinite state. appInsightsLogger.LogWarning($"Unable to send request to backend. Status: {res.StatusCode.ToString()}, Reason: {res.ReasonPhrase}", backendUri, taskId); await UpdateTaskStatus(taskId, backendUri, messageBody, $"Unable to send request to backend.", "failed", appInsightsLogger); } else { await messageReceiver.CompleteAsync(message.SystemProperties.LockToken); appInsightsLogger.LogInformation($"taskId {taskId} has successfully been pushed to the backend from queue {queueName}. Queue time: {elapsedTimeMs/60} seconds.", backendUri, taskId); } } catch (Exception ex) { appInsightsLogger.LogError(ex, backendUri, taskId); } }
public static void Run([TimerTrigger("*/30 * * * * *")] TimerInfo myTimer, ILogger logger) { // CRON expression syntax: <second> <minute> <hour> <day-of-month> <month> <day-of-week> <year> <command> AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); QueueLogger queueLogger = new QueueLogger(appInsightsLogger); queueLogger.LogQueueLength(BACKEND_STATUS_CREATED_PATTERN, adjustment: 1); // Add 1 so that we account for > 1 waiting. }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger logger) { AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); var redisOperation = "increment"; if (req.Body != null) { string body = string.Empty; try { using (StreamReader reader = new StreamReader(req.Body)) { if (reader.BaseStream.Length > 0) { body = reader.ReadToEnd(); ProcessingUpdate update = null; try { update = JsonConvert.DeserializeObject <ProcessingUpdate>(body); } catch { update = JsonConvert.DeserializeObject <ProcessingUpdate[]>(body)[0]; } if (update == null) { appInsightsLogger.LogWarning("Parameters missing. Unable to update processing count."); return(new BadRequestResult()); } else { return(await RedisUpsert(update, appInsightsLogger, redisOperation)); } } else { appInsightsLogger.LogWarning("Parameters missing. Unable to update processing count."); return(new BadRequestResult()); } } } catch (Exception ex) { appInsightsLogger.LogError(ex); appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, DateTime.UtcNow.ToString(), body); return(new StatusCodeResult(500)); } } else { return(new BadRequestResult()); } }
public async Task <HttpResponseMessage> Post([FromBody] Activity activity, CancellationToken cancellationToken) { // Get the current culture info to use in resource files if (activity.Locale != null) { } // This name is sent by MS Teams to indicate sign in. We do this so that we can pass handling to the right logic in the dialog. You can // set this to be whatever string you want. if (activity.Name == Constants.VerifyState) { activity.Text = Constants.SignInCompleteText; } if (activity.Type == ActivityTypes.Message || activity.Name == Constants.VerifyState) { if (activity.ChannelId == Constants.ActivityChannelId) { JObject tenant = activity.ChannelData as JObject; string tenantId = tenant["tenant"].SelectToken("id").ToString(); AppInsightsLogger.CustomEventTrace("Received Input Message for Bot", new Dictionary <string, string>() { { "TenantId", tenantId }, { "User", activity.From.Id }, { "methodName", "Post" }, { "Capability", "Bot" } }); } MicrosoftAppCredentials.TrustServiceUrl($"{activity.ServiceUrl}", DateTime.MaxValue); // Adding typing indicator to incoming message var typingReply = activity.CreateReply(); typingReply.Type = ActivityTypes.Typing; IConnectorClientFactory factory = new ConnectorClientFactory(Address.FromActivity(typingReply), new MicrosoftAppCredentials(AppSettings.Instance.MicrosoftAppId, AppSettings.Instance.MicrosoftAppPassword)); await factory.MakeConnectorClient().Conversations.ReplyToActivityAsync(typingReply); using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)) { var dialog = scope.Resolve <IDialog <object> >(); await Conversation.SendAsync(activity, () => dialog, cancellationToken); } } else if (activity.Type == ActivityTypes.ConversationUpdate) { using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)) { var dialog = scope.Resolve <IDialog <object> >(); MicrosoftAppCredentials.TrustServiceUrl($"{activity.ServiceUrl}", DateTime.MaxValue); await Conversation.SendAsync(activity, () => dialog); } } else if (activity.Type == ActivityTypes.Invoke) { return(await this.HandleInvokeMessagesAsync(activity, cancellationToken)); } return(new HttpResponseMessage(HttpStatusCode.Accepted)); }
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, ILogger logger) { // CRON expression syntax: <second> <minute> <hour> <day-of-month> <month> <day-of-week> <year> <command> AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); QueueLogger queueLogger = new QueueLogger(appInsightsLogger); queueLogger.LogQueueLength(BACKEND_STATUS_COMPLETED_PATTERN); queueLogger.LogQueueLength(BACKEND_STATUS_RUNNING_PATTERN); queueLogger.LogQueueLength(BACKEND_STATUS_FAILED_PATTERN); }
public void Test_Telemetry_IsEnabled() { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); logger.BeginScope("test"); logger.Flush(); // Act/Assert Assert.True(logger.IsEnabled(LogLevel.Information)); }
public void TraceLogSendsToAppInsights(LogLevel logLevel, SeverityLevel expectedSeverity) { var logger = new AppInsightsLogger(LogLevel.Debug, _connString, _stubTelemetryChannel); logger.Log(logLevel, _logMessage); _stubTelemetryChannel.Flush(); Assert.AreEqual(_logMessage, _stubTelemetryChannel.ResponseText); Assert.IsNotNull(_stubTelemetryChannel.ResponseSeverityLevel); Assert.AreEqual(expectedSeverity, _stubTelemetryChannel.ResponseSeverityLevel); }
/// <summary> /// show employees on approved leave. /// </summary> /// <param name="context">dialog context.</param> /// <param name="result">awaitable result.</param> /// <returns>employee on leave card.</returns> private async Task ShowEmployeesonLeaveAsync(IDialogContext context, IAwaitable <string> result) { string message = await result; string jSession = string.Empty; string personNumber = string.Empty; string startDate = default(string); string endDate = default(string); JObject tenant = context.Activity.ChannelData as JObject; string tenantId = tenant["tenant"].SelectToken("id").ToString(); if (context.UserData.TryGetValue(context.Activity.From.Id, out this.response)) { personNumber = this.response.PersonNumber; jSession = this.response.JsessionID; } AppInsightsLogger.CustomEventTrace("OnLeaveDialog", new Dictionary <string, string>() { { "TenantId", tenantId }, { "User", context.Activity.From.Id }, { "methodName", "ShowEmployeesonLeaveAsync" }, { "Command", message } }); // todays date startDate = context.Activity.LocalTimestamp.Value.DateTime.Date.ToString(ApiConstants.DateFormat, CultureInfo.InvariantCulture); endDate = context.Activity.LocalTimestamp.Value.DateTime.Date.ToString(ApiConstants.DateFormat, CultureInfo.InvariantCulture); // get person number from employee name Response hyperFindResponse = await this.hyperFindActivity.GetHyperFindQueryValues(tenantId, jSession, startDate, endDate, ApiConstants.ReportsToHyperFindQuery, ApiConstants.PersonalVisibilityCode); if (hyperFindResponse?.Status == ApiConstants.Success) { var leaveResult = await this.supervisorViewTimeOffActivity.GetTimeOffRequest(tenantId, jSession, startDate, endDate, hyperFindResponse?.HyperFindResult); if (leaveResult?.Status == ApiConstants.Success) { OvertimeMappingEntity entitySick = await this.azureTableStorageHelper.ExecuteQueryUsingPointQueryAsync <OvertimeMappingEntity>(Constants.ActivityChannelId, tenantId + "$" + Constants.SickAZTS, AppSettings.Instance.OvertimeMappingtableName); OvertimeMappingEntity entityVacation = await this.azureTableStorageHelper.ExecuteQueryUsingPointQueryAsync <OvertimeMappingEntity>(Constants.ActivityChannelId, tenantId + "$" + Constants.VacationAZTS, AppSettings.Instance.OvertimeMappingtableName); var vacationResult = leaveResult?.RequestMgmt?.RequestItems?.GlobalTimeOffRequestItem?.FindAll(x => (x.TimeOffPeriods?.TimeOffPeriod.PayCodeName.ToLowerInvariant() == entityVacation?.PayCodeName.ToLowerInvariant() || x.TimeOffPeriods?.TimeOffPeriod.PayCodeName.ToLowerInvariant() == entitySick?.PayCodeName.ToLowerInvariant()) && x.StatusName.ToLowerInvariant() == Constants.Approved.ToLowerInvariant()); Dictionary <string, string> resultData = new Dictionary <string, string>(); foreach (var v in vacationResult) { var employee = hyperFindResponse.HyperFindResult.Where(x => x.PersonNumber.Contains(v.CreatedByUser.PersonIdentity.PersonNumber)).FirstOrDefault(); resultData.Add(employee.FullName, v.TimeOffPeriods.TimeOffPeriod.PayCodeName); } await this.heroLeaveCard.ShowEmployeesonLeaveCard(context, resultData); } } context.Done(default(string)); }
public void Test_Telemetry_LogLevelInfoWithEvent() { AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Information); // Act logger.Log(LogLevel.Information, new EventId(1, "test"), "test", null, null); logger.Flush(); }); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger logger) { IDatabase db = null; AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); string cluster = string.Empty; string path = string.Empty; var apiParams = req.GetQueryParameterDictionary(); if (apiParams != null && apiParams.Keys.Contains(SERVICE_CLUSTER_KEY_NAME) && apiParams.Keys.Contains(API_PATH_KEY_NAME)) { cluster = apiParams[SERVICE_CLUSTER_KEY_NAME]; path = apiParams[API_PATH_KEY_NAME]; } else { return(new BadRequestObjectResult("The cluster and path parameters are requried.")); } try { db = RedisConnection.GetDatabase(); } catch (Exception ex) { appInsightsLogger.LogError(ex, cluster + "/" + path); return(new StatusCodeResult(500)); } RedisValue storedCount = RedisValue.Null; try { storedCount = await db.StringGetAsync(APP_INSIGHTS_REQUESTS_KEY_NAME + cluster + "/" + path); if (storedCount.HasValue) { appInsightsLogger.LogInformation("Found status in cache", cluster + "/" + path); return(new OkObjectResult(storedCount.ToString())); } else { appInsightsLogger.LogInformation("Found status in cache", cluster + "/" + path); return(new StatusCodeResult(204)); } } catch (Exception ex) { appInsightsLogger.LogError(ex, cluster + "/" + path); return(new StatusCodeResult(500)); } }
public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger logger) { IDatabase db = null; AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); string uuid = "nil"; var apiParams = req.GetQueryParameterDictionary(); if (apiParams != null && apiParams.Keys.Contains(UUID_KEYNAME)) { uuid = apiParams[UUID_KEYNAME]; appInsightsLogger.LogInformation("Getting status for taskId: " + uuid, URL, uuid); } else { appInsightsLogger.LogWarning("Called without a taskId", URL); return(new BadRequestObjectResult("The taskId parameter is requried.")); } try { db = RedisConnection.GetDatabase(); } catch (Exception ex) { appInsightsLogger.LogError(ex, URL, uuid); return(new StatusCodeResult(500)); } RedisValue storedStatus = RedisValue.Null; try { storedStatus = db.StringGet(uuid); if (storedStatus.HasValue) { appInsightsLogger.LogInformation("Found status in cache", URL, uuid); return(new OkObjectResult(storedStatus.ToString())); } else { appInsightsLogger.LogWarning("Cannot find status in cache", URL, uuid); return(new StatusCodeResult(204)); } } catch (Exception ex) { appInsightsLogger.LogError(ex, URL, uuid); return(new StatusCodeResult(500)); } }
public void OnlyTracesAboveEnableLevelAreLogged() { var logger = new AppInsightsLogger(LogLevel.Warning, _connString, _stubTelemetryChannel); logger.Log(LogLevel.Information, _logMessage); logger.Log(LogLevel.Critical, _logMessage); _stubTelemetryChannel.Flush(); Assert.AreEqual(_logMessage, _stubTelemetryChannel.ResponseText); Assert.AreEqual(SeverityLevel.Critical, _stubTelemetryChannel.ResponseSeverityLevel); }
public void Test_Telemetry_LogExceptionWithMessage() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogError(new Exception(), "Some error"); logger.Flush(); }); }
public void Test_Telemetry_LogWarningException() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogWarning(new Exception()); logger.Flush(); }); }
public void Test_Telemetry_LogCriticalMessage() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogCritical("test"); logger.Flush(); }); }
public void Test_Telemetry_LogWithWrongLevel() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Warning); // Act logger.LogDebug("test"); logger.Flush(); }); }
public void Test_Telemetry_LogLevelNoneWithException() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.None); // Act logger.Log(LogLevel.Trace, new EventId(1, "test"), "test", new Exception(), null); logger.Flush(); }); }
/// <summary> /// Publishes the event to be processed. /// Depending on configuration sends to Event Grid or Service Bus /// </summary> /// <returns></returns> private static async Task <bool> PublishEvent(APITask task, string taskBody, AppInsightsLogger appInsightsLogger) { var eventGridTopicUri = Environment.GetEnvironmentVariable(EVENT_GRID_TOPIC_URI_VARIABLE_NAME, EnvironmentVariableTarget.Process); var eventGridKey = Environment.GetEnvironmentVariable(EVENT_GRID_KEY_VARIABLE_NAME, EnvironmentVariableTarget.Process); if (string.IsNullOrEmpty(eventGridTopicUri) || string.IsNullOrEmpty(eventGridKey)) { return(await PublishServiceBusQueueEvent(task, taskBody, appInsightsLogger)); } else { return(await PublishEventGridEvent(task, taskBody, eventGridTopicUri, eventGridKey, appInsightsLogger)); } }
public void Test_Telemetry_ExceptionWithDictionary() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogError(new Exception(), new Dictionary <string, string> { { "a", "a" } }); logger.Flush(); }); }
public void Test_Telemetry_LogMetricWithProperties() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogMetric("test", 3.1, new Dictionary <string, string> { { "a", "a" }, { "b", "b" } }); logger.Flush(); }); }
public void Test_Telemetry_LogExceptionWithMessageAndProperties() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); // Act logger.LogError(new Exception(), "Some error", new Dictionary <string, string>() { { "test", "test" } }); logger.Flush(); }); }
private async Task SaveWorkRuleTransfer(IDialogContext context, IAwaitable <string> result) { var command = await result; context.PrivateConversationData.TryGetValue($"{context.Activity.From.Id}WorkRule", out string workRuleName); var activity = context.Activity as Activity; string jSession = this.response.JsessionID; JObject tenant = context.Activity.ChannelData as JObject; string tenantId = tenant["tenant"].SelectToken("id").ToString(); string personNumber = string.Empty; if (context.UserData.TryGetValue(context.Activity.From.Id, out this.response)) { personNumber = this.response.PersonNumber; } AppInsightsLogger.CustomEventTrace("SaveWorkRuleTransferDialog", new Dictionary <string, string>() { { "TenantId", tenantId }, { "User", context.Activity.From.Id }, { "methodName", "SaveWorkRuleTransfer" }, { "Command", command } }); if (command.ToLowerInvariant() == Constants.Yes) { var addPunchResponse = await this.addPunchActivity.AddPunch(tenantId, jSession, personNumber, context.Activity.LocalTimestamp, workRuleName); var error = await this.CheckErrorResponse(addPunchResponse, context); if (!error) { await context.PostAsync(KronosResourceText.PunchWithTransferDone.Replace("{workRuleName}", workRuleName).Replace("{txt}", context.Activity.LocalTimestamp.Value.DateTime.ToString("dddd, dd MMMM yyyy h:mm tt", CultureInfo.InvariantCulture))); context.PrivateConversationData.SetValue($"{context.Activity.From.Id}WorkRule", string.Empty); } } else if (command.ToLowerInvariant() == Constants.No) { await context.PostAsync(KronosResourceText.TransferCanceled); } context.Done(string.Empty); }
public void Test_Telemetry_LogInformationMessage() { // Assert AssertExtensions.DoesNotThrow(() => { // Arrange var logger = new AppInsightsLogger("test", LogLevel.Trace); Dictionary <string, string> statistics = new Dictionary <string, string>() { { "SomeProp1", "sample1" }, { "SomeProp2", "sample2" }, { "SomeProp3", "sample3" } }; logger.LogInformation("test title", statistics); logger.Log(LogLevel.Information, new EventId(1, null), "A", null, (a, b) => { return(string.Format("{0}:{1}", a, b)); }); logger.Flush(); }); }
public override void OnException(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext?.Exception != null) { if (AppSettings.Instance.LogInsightsFlag == "1") { AppInsightsLogger.Error(actionExecutedContext.Exception); } var errorMessagError = new System.Web.Http.HttpError(actionExecutedContext.Exception.Message); actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, errorMessagError); } else { var response = new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent("An unhandled exception was thrown by service"), ReasonPhrase = "Internal Server Error.Please Contact your Administrator.", }; actionExecutedContext.Response = response; } }
public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger logger) { IDatabase db = null; AppInsightsLogger appInsightsLogger = new AppInsightsLogger(logger, LOGGING_SERVICE_NAME, LOGGING_SERVICE_VERSION); var redisOperation = "insert"; APITask task = null; if (req.Body != null) { string body = string.Empty; try { using (StreamReader reader = new StreamReader(req.Body)) { if (reader.BaseStream.Length > 0) { body = reader.ReadToEnd(); logger.LogInformation("body: " + body); try { appInsightsLogger.LogInformation("DeserializeObject<APITask>(body)"); task = JsonConvert.DeserializeObject <APITask>(body); } catch { appInsightsLogger.LogInformation("DeserializeObject<APITask>(body[])"); task = JsonConvert.DeserializeObject <APITask[]>(body)[0]; } appInsightsLogger.LogInformation("task.PublishToGrid: " + task.PublishToGrid.ToString(), task.Endpoint, task.TaskId); } else { appInsightsLogger.LogWarning("Parameters missing. Unable to create task."); return(new BadRequestResult()); } } } catch (Exception ex) { appInsightsLogger.LogError(ex); appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, body); return(new StatusCodeResult(500)); } } else { appInsightsLogger.LogWarning("Parameters missing. Unable to create task."); return(new BadRequestResult()); } if (!String.IsNullOrWhiteSpace(task.TaskId)) { appInsightsLogger.LogInformation("Updating status", task.Endpoint, task.TaskId); redisOperation = "update"; } else { task.TaskId = Guid.NewGuid().ToString(); appInsightsLogger.LogInformation("Generated new taskId: " + task.TaskId, task.Endpoint, task.TaskId); } task.Timestamp = DateTime.UtcNow.ToString(); try { db = RedisConnection.GetDatabase(); } catch (Exception ex) { appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId); appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, task.Endpoint, task.TaskId); return(new StatusCodeResult(500)); } string serializedTask = string.Empty; try { var taskBody = task.Body; task.Body = null; serializedTask = JsonConvert.SerializeObject(task); RedisValue res = RedisValue.Null; appInsightsLogger.LogInformation("Setting Redis task record", task.Endpoint, task.TaskId); var upsertTransaction = db.CreateTransaction(); upsertTransaction.StringSetAsync(task.TaskId, serializedTask); // Get seconds since epoch TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1)); int timestamp = (int)ts.TotalSeconds; appInsightsLogger.LogInformation(string.Format("Adding backend status '{0}' for endpoint.", task.BackendStatus), task.Endpoint, task.TaskId); upsertTransaction.SortedSetAddAsync(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), new SortedSetEntry[] { new SortedSetEntry(task.TaskId, timestamp) }); if (task.BackendStatus.Equals(BACKEND_STATUS_RUNNING)) { upsertTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_CREATED), task.TaskId); } else if (task.BackendStatus.Equals(BACKEND_STATUS_COMPLETED) || task.BackendStatus.Equals(BACKEND_STATUS_FAILED)) { upsertTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_RUNNING), task.TaskId); } bool isSubsequentPipelineCall = false; bool isPublish = false; bool.TryParse(task.PublishToGrid.ToString(), out isPublish); if (isPublish == true || task.PublishToGrid == true) { if (string.IsNullOrEmpty(taskBody)) { appInsightsLogger.LogInformation("It IS a pipeline call", task.Endpoint, task.TaskId); // This is a subsequent pipeline publish. isSubsequentPipelineCall = true; } else { appInsightsLogger.LogInformation("Adding body to redis: " + taskBody, task.Endpoint, task.TaskId); upsertTransaction.StringSetAsync(string.Format("{0}_{1}", task.TaskId, GRID_PUBLISH_RECORD_KEY), taskBody); } } ExecuteTransaction(upsertTransaction, task, appInsightsLogger); if (isSubsequentPipelineCall) { // We have to get the original body, since it's currently empty. taskBody = db.StringGet(string.Format("{0}_{1}", task.TaskId, GRID_PUBLISH_RECORD_KEY)); appInsightsLogger.LogInformation("Stored body: " + taskBody, task.Endpoint, task.TaskId); } if (task.PublishToGrid) { if (PublishEvent(task, taskBody, appInsightsLogger) == false) { // Move task to failed var updateTransaction = db.CreateTransaction(); task.Status = "Failed - unable to send to backend service."; task.BackendStatus = BACKEND_STATUS_FAILED; string updateBody = JsonConvert.SerializeObject(task); updateTransaction.StringSetAsync(task.TaskId, updateBody); updateTransaction.SortedSetAddAsync(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), new SortedSetEntry[] { new SortedSetEntry(task.TaskId, timestamp) }); updateTransaction.SortedSetRemoveAsync(string.Format("{0}_{1}", task.EndpointPath, BACKEND_STATUS_CREATED), task.TaskId); ExecuteTransaction(updateTransaction, task, appInsightsLogger); } } //LogSetCount(string.Format("{0}_{1}", task.EndpointPath, task.BackendStatus), task, db, appInsightsLogger); appInsightsLogger.LogRedisUpsert("Redis upsert successful.", redisOperation, task.Timestamp, serializedTask, task.Endpoint, task.TaskId); } catch (Exception ex) { appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId); appInsightsLogger.LogRedisUpsert("Redis upsert failed.", redisOperation, task.Timestamp, serializedTask, task.Endpoint, task.TaskId); return(new StatusCodeResult(500)); } return(new OkObjectResult(serializedTask)); }
private static void LogSetCount(string setName, APITask task, IDatabase db, AppInsightsLogger appInsightsLogger) { var len = db.SortedSetLength(setName); appInsightsLogger.LogMetric(setName, len, task.EndpointPath); }
private static void ExecuteTransaction(ITransaction transaction, APITask task, AppInsightsLogger appInsightsLogger) { int attempt = 1; TimeSpan delaySeconds = TimeSpan.FromSeconds(0); var tran = transaction.ExecuteAsync(); while (transaction.Wait(tran) == false) { Task.Delay(delaySeconds).GetAwaiter().GetResult(); if (attempt >= 5) { var ex = new Exception("Unable to complete redis transaction."); appInsightsLogger.LogError(ex, task.Endpoint, task.TaskId); throw ex; } delaySeconds.Add(TimeSpan.FromSeconds(2)); attempt++; } }