Esempio n. 1
0
        /// <summary>
        /// Handles events that require the document retrieval
        /// This will get the metadata and pull the documents and optionally create an index file for the documents
        /// </summary>
        /// <param name="eventData"></param>
        private static void DocumentRetrievalHandler(EventNotificationData eventData)
        {
            var manager = new DocumentManager();

            if (eventData.PropertyValues[EventPropertyConstants.SvDocumentId].IsNullOrEmpty())
            {
                logger.ErrorFormat("DataService ProcessPostedEvent Missing Document Id for Event Id: {0}", eventData.PropertyValues[EventPropertyConstants.Id].Value <string>());
                return;
            }

            //First make sure we have the document metadata otherwise get it
            if (eventData.DocumentMetaData.Id == 0)
            {
                eventData.DocumentMetaData = manager.GetDocumentMetaData(eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>());
            }

            //Get and Store the Documents
            var dataFiles = manager.GetDocumentFiles(eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>(), eventData);

            //If required create an index file
            if (dataFiles.Any() && (campusLogicConfigSection.DocumentSettings.IndexFileEnabled ?? false))
            {
                manager.CreateDocumentsIndexFile(dataFiles, eventData);
            }
        }
Esempio n. 2
0
        public static void GetDefaultDatabaseProcedure(EventNotificationData eventData, string storedProcedureName)
        {
            var parameters = new List <OdbcParameter>();

            //Define parameters
            parameters.Add(new OdbcParameter
            {
                ParameterName = "StudentId",
                OdbcType      = OdbcType.VarChar,
                Size          = 9,
                Value         = eventData.PropertyValues[EventPropertyConstants.StudentId].Value <string>()
            });

            parameters.Add(new OdbcParameter
            {
                ParameterName = "AwardYear",
                OdbcType      = OdbcType.VarChar,
                Size          = 4,
                Value         = eventData.PropertyValues[EventPropertyConstants.AwardYear].IsNullOrEmpty() ? string.Empty : (eventData.PropertyValues[EventPropertyConstants.AwardYear].Value <string>().Substring(2, 2) + eventData.PropertyValues[EventPropertyConstants.AwardYear].Value <string>().Substring(7, 2))
            });

            parameters.Add(new OdbcParameter
            {
                ParameterName = "TransactionCategoryId",
                OdbcType      = OdbcType.Int,
                Value         = eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].IsNullOrEmpty() ? 0 : eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].Value <int>()
            });

            parameters.Add(new OdbcParameter
            {
                ParameterName = "EventNotificationId",
                OdbcType      = OdbcType.Int,
                Value         = eventData.PropertyValues[EventPropertyConstants.EventNotificationId].Value <int>()
            });

            if (!eventData.PropertyValues[EventPropertyConstants.SvDocumentId].IsNullOrEmpty() && eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>() > 0)
            {
                var manager = new DocumentManager();
                DocumentMetaData metaData = manager.GetDocumentMetaData(eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>());

                parameters.Add(new OdbcParameter
                {
                    ParameterName = "DocumentName",
                    OdbcType      = OdbcType.VarChar,
                    Size          = 128,
                    Value         = metaData != null ? metaData.DocumentName : string.Empty
                });
            }
            else
            {
                parameters.Add(new OdbcParameter
                {
                    ParameterName = "DocumentName",
                    OdbcType      = OdbcType.VarChar,
                    Size          = 128,
                    Value         = string.Empty
                });
            }
            ClientDatabaseManager.ExecuteDatabaseStoredProcedure("{CALL " + storedProcedureName + " (?, ?, ?, ?, ?)}", parameters);
        }
Esempio n. 3
0
        /// <summary>
        /// Handles events that require the system to execute a database stored procedure based on the configuration.
        /// </summary>
        /// <param name="eventData"></param>
        /// <param name="storedProcedureName"></param>
        private static void DatabaseStoredProcedure(EventNotificationData eventData, string storedProcedureName)
        {
            var storedProcedureSettings = campusLogicConfigSection.StoredProcedures.GetStoredProcedure(storedProcedureName);

            if (storedProcedureSettings != null)
            {
                // Parse parameters based on config.
                List <OdbcParameter> parameters =
                    storedProcedureSettings.GetParameters().Select(p => ParseParameter(p, eventData)).ToList();

                //Adding logging in case client experiences weird argument error, we can better determine what we are trying to pass
                //logger.Info($"Parameters to be pass into database: { String.Join(", ", parameters.Select(x => x.ParameterName + ": " + x.Value.ToString() + " - DataType: " + Enum.GetName(typeof(OdbcType), x.OdbcType)))}");

                // For each parameter, need to add a placeholder "?" in the sql command.
                // This is just part of the ODBC syntax.
                string placeholders = string.Join(",", parameters.Select(p => "?").ToArray());
                if (placeholders.Length > 0)
                {
                    placeholders = " (" + placeholders + ")";
                }

                // Final output should look like this: {CALL sproc_name (?, ?, ?)}
                string command = $"{{CALL {storedProcedureSettings.Name}{placeholders}}}";

                //logger.Info(command);
                ClientDatabaseManager.ExecuteDatabaseStoredProcedure(command, parameters);
            }
            else
            {
                //Static db procedure
                GetDefaultDatabaseProcedure(eventData, storedProcedureName);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Used for getting a batch of AL PDFs for printing.
        /// </summary>
        /// <param name="eventData"></param>
        private static void BatchProcessRetrievalHandler(string type, string name, EventNotificationData eventData)
        {
            var message = eventData.PropertyValues.ToString().Replace("'", "''");

            using (var dbContext = new CampusLogicContext())
            {
                //Insert the event into the BatchProcessRecord table so that it can be processed by the Automated Batch Process job.
                dbContext.Database.ExecuteSqlCommand($"INSERT INTO [dbo].[BatchProcessRecord]([Type], [Name], [Message], [ProcessGuid], [RetryCount], [RetryUpdatedDate]) VALUES('{type}', '{name}', '{message}', NULL, NULL, NULL)");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Used to get PDF
        /// version of AL
        /// for printers
        /// </summary>
        /// <param name="eventData"></param>
        private static void AwardLetterDocumentRetrievalHandler(EventNotificationData eventData)
        {
            var manager = new DocumentManager();

            if (eventData.PropertyValues[EventPropertyConstants.AlRecordId].IsNullOrEmpty())
            {
                logger.ErrorFormat("DataService ProcessPostedEvent Missing Record Id for Event Id: {0}", eventData.PropertyValues[EventPropertyConstants.Id].Value <string>());
                return;
            }

            //Get and Store the Documents
            manager.GetAwardLetterPdfFile(Guid.Parse(eventData.PropertyValues[EventPropertyConstants.AlRecordId].Value <string>()), eventData);
        }
Esempio n. 6
0
 // Update event list for given team id
 private void AddEventNotificationForTeam(string teamId, EventNotificationData eventNotificationData)
 {
     if (this.teamToEventNotificationsMap.TryGetValue(teamId, out List <EventNotificationData> events))
     {
         events.Add(eventNotificationData);
     }
     else
     {
         this.teamToEventNotificationsMap.Add(teamId, new List <EventNotificationData> {
             eventNotificationData
         });
     }
 }
Esempio n. 7
0
 /// <summary>
 /// The File Store Handler. Surprise!
 /// </summary>
 public static void FileStoreHandler(EventNotificationData eventData)
 {
     try
     {
         using (var dbContext = new CampusLogicContext())
         {
             var dataToSerialize = eventData.PropertyValues.ToString().Replace("'", "''");
             //Insert the event into the EventNotification table so that it can be processed by the Automated File Store job.
             dbContext.Database.ExecuteSqlCommand($"INSERT INTO [dbo].[EventNotification]([EventNotificationId], [Message], [CreatedDateTime], [ProcessGuid]) VALUES({eventData.PropertyValues[EventPropertyConstants.EventNotificationId].Value<int>()}, '{dataToSerialize}', GetUtcDate(), NULL)");
         }
     }
     catch (Exception ex)
     {
         logger.Error($"An error occured when attempting to handle the event data for file store: {ex}");
     }
 }
        public static async Task RunBatchProcess(string type, string name, int size)
        {
            logger.Info("enter batch processing");
            Guid processGuid = Guid.NewGuid();

            using (var dbContext = new CampusLogicContext())
            {
                try
                {
                    // Get all records in our LocalDB to process
                    var records = dbContext.BatchProcessRecords.Where(b => b.Name == name && b.Type == type && b.ProcessGuid == null);

                    if (records.Any())
                    {
                        // Lock these records from being processed again
                        dbContext.Database.ExecuteSqlCommand($"UPDATE[dbo].[BatchProcessRecord] SET[ProcessGuid] = '{processGuid}' FROM [dbo].[BatchProcessRecord] WHERE[Id] IN(SELECT [Id] from[dbo].[BatchProcessRecord] WHERE [Type] = '{type}' AND [Name] = '{name}' AND [ProcessGuid] IS NULL)");

                        // Ensure there are locked records with this process guid
                        if (dbContext.BatchProcessRecords.Any(b => b.ProcessGuid != null && b.ProcessGuid == processGuid))
                        {
                            if (type == ConfigConstants.AwardLetterPrintBatchType)
                            {
                                var manager = new DocumentManager();
                                Dictionary <int, Guid> recordIds = new Dictionary <int, Guid>();

                                var recordList = dbContext.BatchProcessRecords.Where(b => b.ProcessGuid == processGuid).Select(b => b).ToList();
                                // Get all records with this process guid
                                foreach (var record in recordList)
                                {
                                    // Deserialize the message
                                    var eventData = new EventNotificationData(JObject.Parse(record.Message));

                                    //Track retry attempts
                                    var now = DateTime.Now;
                                    var processSingularly  = false;
                                    var retryTimeHasPassed = !record.RetryUpdatedDate.HasValue || record.RetryUpdatedDate.Value.AddHours(1) < DateTime.Now;
                                    if (record.RetryCount == null)
                                    {
                                        record.RetryCount = 1;
                                        dbContext.Database.ExecuteSqlCommand($"UPDATE[dbo].[BatchProcessRecord] SET [RetryCount] = 1, [RetryUpdatedDate] = '{now}' FROM [dbo].[BatchProcessRecord] WHERE[Id] = {record.Id}");
                                    }
                                    else if (retryTimeHasPassed || record.RetryCount == RETRY_MAX)
                                    {
                                        record.RetryCount = record.RetryCount + 1;
                                        dbContext.Database.ExecuteSqlCommand($"UPDATE[dbo].[BatchProcessRecord] SET [RetryCount] = [RetryCount] + 1, [RetryUpdatedDate] = '{now}'  FROM [dbo].[BatchProcessRecord] WHERE[Id] = {record.Id}");
                                    }

                                    if (eventData.PropertyValues[EventPropertyConstants.AlRecordId].IsNullOrEmpty())
                                    {
                                        SendErrorNotification("Batch AwardLetter process", $"This record has no AL-record-Id, record Id: {eventData.PropertyValues[EventPropertyConstants.Id].Value<string>()}. This likely means the notification event is not an AL event.  Please contact your CampusLogic contact for next steps.");
                                        logger.Error($"Record for batch awardletter process has no AL-record-Id, with award letter record Id: {eventData.PropertyValues[EventPropertyConstants.Id].Value<string>()}.  This likely means the notification event is not an AL event");
                                        dbContext.Database.ExecuteSqlCommand($"DELETE FROM [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] = {record.Id}");
                                    }
                                    else if (record.RetryCount > RETRY_MAX)
                                    {
                                        SendErrorNotification("Batch AwardLetter process", $"This record has reached it's maximum retry attempts, record Id: {record.Id}, AL-record-Id: {Guid.Parse(eventData.PropertyValues[EventPropertyConstants.AlRecordId].Value<string>())}. Please contact your CampusLogic contact for next steps.");
                                        logger.Error($"Record for batch awardletter process has reached maximum retry attempts, with award letter record Id: {record.Id}, AL-record-Id: {Guid.Parse(eventData.PropertyValues[EventPropertyConstants.AlRecordId].Value<string>())}.");
                                        dbContext.Database.ExecuteSqlCommand($"DELETE FROM [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] = {record.Id}");
                                    }
                                    else if (record.RetryCount == RETRY_MAX && retryTimeHasPassed)
                                    {
                                        processSingularly = true;
                                        recordIds.Add(record.Id, Guid.Parse(eventData.PropertyValues[EventPropertyConstants.AlRecordId].Value <string>()));
                                    }
                                    else if (retryTimeHasPassed)
                                    {
                                        processSingularly = false;
                                        recordIds.Add(record.Id, Guid.Parse(eventData.PropertyValues[EventPropertyConstants.AlRecordId].Value <string>()));
                                    }

                                    if (recordIds.Count == size || processSingularly)
                                    {
                                        // Get event data for index file creation
                                        var recordIdList = string.Join(",", recordIds.Keys);
                                        var message      = new EventNotificationData(JObject.Parse(dbContext.Database.SqlQuery <string>($"SELECT [Message] from [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] IN ({recordIdList})").First()));

                                        var response = await manager.GetBatchAwardLetterPdfFile(recordIds.Values.ToList(), name, message);

                                        //If the response was successful remove those records from the db so
                                        //we do not continue to process them if the file fails
                                        if (response.IsSuccessStatusCode)
                                        {
                                            dbContext.Database.ExecuteSqlCommand($"DELETE FROM [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] IN ({recordIdList})");
                                        }
                                        recordIds.Clear();
                                    }
                                }

                                // Process the last group of records that was smaller than the batch size
                                if (recordIds.Any())
                                {
                                    var recordIdList = string.Join(",", recordIds.Keys);
                                    var message      = new EventNotificationData(JObject.Parse(dbContext.Database.SqlQuery <string>($"SELECT [Message] from [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] IN ({recordIdList})").First()));

                                    var response = await manager.GetBatchAwardLetterPdfFile(recordIds.Values.ToList(), name, message);

                                    if (response.IsSuccessStatusCode)
                                    {
                                        dbContext.Database.ExecuteSqlCommand($"DELETE FROM [dbo].[BatchProcessRecord] WHERE [ProcessGuid] = '{processGuid}' and [Id] IN ({recordIdList})");
                                    }
                                }
                                dbContext.Database.ExecuteSqlCommand($"UPDATE [dbo].[BatchProcessRecord] SET [ProcessGuid] = NULL WHERE [ProcessGuid] = '{processGuid}'");
                            }
                        }
                    }
                }

                catch (TaskCanceledException ex)
                {
                    logger.Error($"The task was canceled: {ex}");
                    if (ex.InnerException != null)
                    {
                        logger.Error($"Inner exception: {ex.InnerException}");
                    }
                }
                catch (Exception e)
                {
                    //Something happened during processing. Update any records that may have been marked for processing back to null so that they can be re-processed.
                    logger.Error($"An error occured while attempting to execute the batch process: {e}");
                }
                finally
                {
                    dbContext.Database.ExecuteSqlCommand($"UPDATE [dbo].[BatchProcessRecord] SET [ProcessGuid] = NULL WHERE [ProcessGuid] = '{processGuid}'");
                }
            }
        }
Esempio n. 9
0
        public static void ProcessFileStore()
        {
            //Guid to be applied to the records in the EventNotification table
            Guid processGuid = Guid.NewGuid();

            using (var dbContext = new CampusLogicContext())
            {
                //1. Create GUID
                //2. Assign GUID to all existing records in LocalDB table that have null ProcessGuid
                //3. Write to file(s)
                //4. Rinse & Repeat every x minutes.
                try
                {
                    Dictionary <int, EventNotificationData> eventNotificationDataList = new Dictionary <int, EventNotificationData>();
                    List <int> successEventIds = new List <int>();
                    List <int> failEventIds    = new List <int>();

                    //update all the current eventNotification records with no processguid to be processed.
                    dbContext.Database.ExecuteSqlCommand($"UPDATE [dbo].[EventNotification] SET [ProcessGuid] = '{processGuid}' WHERE [ProcessGuid] IS NULL");

                    //make sure there are events to process
                    if (dbContext.EventNotifications.Any(s => s.ProcessGuid != null && s.ProcessGuid == processGuid))
                    {
                        //Get any individual or shared FileStore events configured from the web.config
                        var individualEvents =
                            campusLogicConfigSection.EventNotifications.Cast <EventNotificationHandler>()
                            .Where(s => s.FileStoreType == "Individual").Select(e => e.EventNotificationId)
                            .ToList();

                        var sharedEvents = campusLogicConfigSection.EventNotifications.Cast <EventNotificationHandler>()
                                           .Where(s => s.FileStoreType == "Shared").Select(e => e.EventNotificationId)
                                           .ToList();

                        if (sharedEvents.Any())
                        {
                            //Make sure the event's processguid matches what we just generated so we're not re-processing events.
                            var sharedEventsToProcess =
                                dbContext.EventNotifications
                                .Where(e => sharedEvents.Contains(e.EventNotificationId) && e.ProcessGuid == processGuid)
                                .Select(m => new { id = m.Id, message = m.Message });

                            foreach (var eventRec in sharedEventsToProcess)
                            {
                                var eventData = new EventNotificationData(JObject.Parse(eventRec.message));

                                eventNotificationDataList.Add(eventRec.id, eventData);
                            }

                            if (eventNotificationDataList.Count > 0)
                            {
                                //send the list of events over to be processed into a file
                                FileStoreManager filestoreManager = new FileStoreManager();
                                filestoreManager.CreateFileStoreFile(eventNotificationDataList, ref successEventIds, ref failEventIds);
                                eventNotificationDataList.Clear();

                                CleanEventNotificationRecords(processGuid, ref successEventIds, ref failEventIds);
                            }
                        }

                        if (individualEvents.Any())
                        {
                            var individualEventsToProcess = dbContext.EventNotifications.Where(e => individualEvents.Contains(e.EventNotificationId) && e.ProcessGuid == processGuid);

                            //Process any events configured for individual store into separate files (e.g., all 104 events in one file, all 105 in another)
                            foreach (int eventNotificationId in individualEvents)
                            {
                                foreach (var eventRec in individualEventsToProcess.Where(s => s.EventNotificationId == eventNotificationId).Select(m => new { id = m.Id, message = m.Message }))
                                {
                                    var eventData = new EventNotificationData(JObject.Parse(eventRec.message));
                                    eventNotificationDataList.Add(eventRec.id, eventData);
                                }

                                if (eventNotificationDataList.Count > 0)
                                {
                                    FileStoreManager filestoreManager = new FileStoreManager();
                                    filestoreManager.CreateFileStoreFile(eventNotificationDataList, ref successEventIds, ref failEventIds);
                                    //clear out the list now that we've completed processing
                                    eventNotificationDataList.Clear();

                                    CleanEventNotificationRecords(processGuid, ref successEventIds, ref failEventIds);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    //Something happened during processing. Update any records that may have been marked for processing back to null so that they can be re-processed.
                    logger.Error($"An error occured while attempting to process the event(s) for file store: {ex}");
                    dbContext.Database.ExecuteSqlCommand($"UPDATE [dbo].[EventNotification] SET [ProcessGuid] = NULL WHERE [ProcessGuid] = '{processGuid}'");
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Handles an HTTP request for an endpoint.
        /// </summary>
        /// <param name="endpointName"></param>
        /// <param name="eventData"></param>
        private static void ApiIntegrationsHandler(string endpointName, EventNotificationData eventData)
        {
            try
            {
                using (var httpClient = new System.Net.Http.HttpClient())
                {
                    var apiEndpoint = campusLogicConfigSection.ApiEndpoints.GetEndpoints().FirstOrDefault(e => e.Name == endpointName);
                    if (apiEndpoint == null)
                    {
                        throw new Exception("Invalid API Endpoint");
                    }

                    var apiIntegration = campusLogicConfigSection.ApiIntegrations.GetApiIntegrations().FirstOrDefault(a => a.ApiId == apiEndpoint.ApiId);
                    if (apiIntegration == null)
                    {
                        throw new Exception("Invalid API Integration");
                    }

                    httpClient.BaseAddress = new Uri(apiIntegration.Root);

                    // Allow 5 minutes for response
                    httpClient.Timeout = new TimeSpan(0, 5, 0);

                    // Custom header for API service to track requests
                    httpClient.DefaultRequestHeaders.Add("EventId", eventData.PropertyValues[EventPropertyConstants.Id].Value <string>());

                    var authType = apiIntegration.Authentication;
                    switch (authType)
                    {
                    case ConfigConstants.Basic:
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                                                                                                       Convert.ToBase64String(
                                                                                                           Encoding.ASCII.GetBytes(
                                                                                                               $"{apiIntegration.Username}:{apiIntegration.Password}")));
                        break;

                    case ConfigConstants.OAuth2:
                        var oauth2Token = GetOauth2TokenAsync(apiIntegration).Result;
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", oauth2Token);
                        break;

                    case ConfigConstants.OAuth_WRAP:
                        var oauthwrapToken = GetOauthWrapTokenAsync(apiIntegration).Result;
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("WRAP", "access_token=\"" + oauthwrapToken + "\"");
                        break;

                    default:
                        break;
                    }

                    // use the eventdata and its values to link up to the endpoint's parameters
                    var parameterMappings           = JArray.Parse(apiEndpoint.ParameterMappings);
                    NameValueCollection eventParams = new NameValueCollection();

                    // foreach mapping, get event property, find its corresponding eventdata, get that eventdata's value, attach it to the parameter in mapping
                    foreach (JObject mapping in parameterMappings)
                    {
                        var eventValue = eventData.PropertyValues[mapping["eventData"].Value <string>()].Value <string>();
                        eventParams.Add(mapping["parameter"].Value <string>(), eventValue);
                    }

                    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

                    var endpoint = apiEndpoint.Endpoint;
                    var url      = apiIntegration.Root + endpoint;

                    switch (apiEndpoint.Method)
                    {
                    case WebRequestMethods.Http.Get:
                        var array = (from key in eventParams.AllKeys
                                     from value in eventParams.GetValues(key)
                                     select $"{HttpUtility.UrlEncode(key)}={HttpUtility.UrlEncode(value)}").ToArray();
                        endpoint += "?" + string.Join("&", array);
                        response  = httpClient.GetAsync(endpoint).Result;
                        break;

                    case WebRequestMethods.Http.Post:
                        response = httpClient.PostAsync(endpoint, GetHttpContent(eventParams, apiEndpoint.MimeType)).Result;
                        break;

                    case WebRequestMethods.Http.Put:
                        response = httpClient.PutAsync(endpoint, GetHttpContent(eventParams, apiEndpoint.MimeType)).Result;
                        break;

                    default:
                        break;
                    }

                    LogRequest(response, eventParams);

                    if (!response.IsSuccessStatusCode)
                    {
                        throw new Exception("Invalid response - " + (int)response.StatusCode + " " + response.ReasonPhrase + " - Attempted to call " + apiEndpoint.Method + " " + url);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ErrorFormat("DataService ApiIntegrationsHandler Error: {0}", e);
                throw;
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Builds an Odbc Parameter object from the arguments.
        /// </summary>
        /// <param name="parameterElement">Parameter definition from the config.</param>
        /// <param name="data">The event notification to pull the parameter's value from.</param>
        /// <returns></returns>
        private static OdbcParameter ParseParameter(ParameterElement parameterElement, EventNotificationData data)
        {
            try
            {
                // Need to convert the string representation of the type to the actual
                // enum OdbcType.
                string[] odbcTypes     = Enum.GetNames(typeof(OdbcType));
                string   odbcTypeMatch = odbcTypes.First(t => t.Equals(parameterElement.DataType, StringComparison.InvariantCultureIgnoreCase));
                OdbcType odbcType      = (OdbcType)Enum.Parse(typeof(OdbcType), odbcTypeMatch);

                // Get property from the data using the property DisplayName (source)
                object value = HttpUtility.HtmlDecode(data.GetValueByDisplayName(parameterElement.Source));

                // Build return object.
                var parameter = new OdbcParameter
                {
                    ParameterName = parameterElement.Name,
                    OdbcType      = odbcType,
                    Size          = parameterElement.LengthAsInt,
                    Value         = value == null ? DBNull.Value : (string)value == string.Empty && odbcType == OdbcType.Int ? 0 : value
                };

                return(parameter);
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to parse parameter.", ex);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Handles events that require the system to execute a non-query database command
        /// </summary>
        /// <param name="eventData"></param>
        /// <param name="databaseCommand"></param>
        private static void DatabaseCommandNonQueryHandler(EventNotificationData eventData, string databaseCommand)
        {
            var commandText = eventData.ReplaceStringProperties(databaseCommand);

            ClientDatabaseManager.ExecuteDatabaseNonQuery(commandText);
        }
Esempio n. 13
0
        /// <summary>
        /// Handles PowerFAIDS integration.
        /// Will either queue up the eventData to be written to a file later
        /// or save the single record as an XML file.
        /// </summary>
        /// <param name="eventData"></param>
        private static void PowerFaidsHandler(EventNotificationData eventData)
        {
            try
            {
                // Get the settings the user has defined for PowerFAIDS
                var generalSettings = campusLogicConfigSection.PowerFaidsSettings;

                var awardYearToken = eventData.PropertyValues[EventPropertyConstants.AwardYear].Value <string>();

                if (!string.IsNullOrEmpty(awardYearToken))
                {
                    awardYearToken = awardYearToken.Split('-')[0];
                }

                var eventSettings = campusLogicConfigSection.PowerFaidsSettings.PowerFaidsSettingCollectionConfig.GetPowerFaidsSettingList();

                var eventSetting = eventSettings
                                   .FirstOrDefault(e => !eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].IsNullOrEmpty() &&
                                                   eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].Value <string>() == e.TransactionCategory &&
                                                   e.Event == eventData.PropertyValues[EventPropertyConstants.EventNotificationId].Value <string>());

                if (eventSetting != null)
                {
                    var recordToProcess = new PowerFaidsDto()
                    {
                        EventId                 = eventData.PropertyValues[EventPropertyConstants.Id].Value <string>(),
                        AwardYearToken          = awardYearToken,
                        AlternateId             = eventData.PropertyValues[EventPropertyConstants.StudentId].Value <string>(),
                        FilePath                = generalSettings.FilePath,
                        Outcome                 = eventSetting.Outcome,
                        ShortName               = eventSetting.ShortName,
                        RequiredFor             = eventSetting.RequiredFor,
                        Status                  = eventSetting.Status,
                        EffectiveDate           = eventData.PropertyValues[EventPropertyConstants.DateTimeUtc].Value <DateTime>().ToString("yyyy-MM-dd"),
                        DocumentLock            = eventSetting.DocumentLock,
                        VerificationOutcome     = eventSetting.VerificationOutcome,
                        VerificationOutcomeLock = eventSetting.VerificationOutcomeLock
                    };

                    if (generalSettings.IsBatch.Value == false)
                    {
                        try
                        {
                            PowerFaidsService.ProcessPowerFaidsRecords(new List <PowerFaidsDto>()
                            {
                                recordToProcess
                            });
                        }
                        catch (Exception)
                        {
                            throw new Exception($"Error occurred while processing PowerFAIDS record. EventId: {recordToProcess.EventId}");
                        }
                    }
                    else
                    {
                        var json = JsonConvert.SerializeObject(recordToProcess).Replace("'", "''");

                        using (var dbContext = new CampusLogicContext())
                        {
                            // Insert the record into the PowerFaidsRecord table so that it can be processed by the Automated PowerFAIDS job.
                            dbContext.Database.ExecuteSqlCommand($"INSERT INTO [dbo].[PowerFaidsRecord]([Json], [ProcessGuid]) VALUES('{json}', NULL)");
                        }
                    }
                }
                else
                {
                    throw new Exception($"Error occured while processing PowerFAIDS record. Cannot find mapping for Event Notification: {eventData.PropertyValues[EventPropertyConstants.EventNotificationId].Value<string>()} and Transaction Category: {eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].Value<string>()}");
                }
            }
            catch (Exception e)
            {
                NotificationService.ErrorNotification("PowerFAIDS", e);
                throw;
            }
        }
Esempio n. 14
0
        public static void ProcessPostedEvent(JObject notificationEvent)
        {
            try
            {
                using (var dbContext = new CampusLogicContext())
                {
                    var eventData = new EventNotificationData(notificationEvent);

                    int eventNotificationId = eventData.PropertyValues[EventPropertyConstants.EventNotificationId].Value <int>();

                    var eventHandler = campusLogicConfigSection.EventNotifications.Cast <EventNotificationHandler>().FirstOrDefault(x => x.EventNotificationId == eventNotificationId) ??
                                       campusLogicConfigSection.EventNotifications.Cast <EventNotificationHandler>().FirstOrDefault(x => x.EventNotificationId == 0); //If no specific handler was provided check for the catch all handler

                    if (eventHandler != null)
                    {
                        //Enhance the Event Data for certain situations

                        //Check if the transaction category was one of the three appeal types
                        if (!eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].IsNullOrEmpty())
                        {
                            if (((TransactionCategory)eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].Value <int>() != TransactionCategory.Verification &&
                                 (TransactionCategory)eventData.PropertyValues[EventPropertyConstants.SvTransactionCategoryId].Value <int>() != TransactionCategory.Generic) && eventData.PropertyValues[EventPropertyConstants.EventNotificationName].Value <string>() == "Transaction Completed")
                            {
                                if (eventData.PropertyValues[EventPropertyConstants.SvTransactionId].IsNullOrEmpty())
                                {
                                    throw new Exception("A transaction Id is needed to get the appeal meta data");
                                }
                                var manager = new AppealManager();
                                manager.GetAuthorizationForSV();
                                eventData.PropertyValues[EventPropertyConstants.TransactionOutcomeId] = manager.GetAppealMetaData(eventData.PropertyValues[EventPropertyConstants.SvTransactionId].Value <int>()).Result.ToString();
                            }
                        }

                        //Was a documentId sent over? If so, populate the Document Metadata.
                        if (!eventData.PropertyValues[EventPropertyConstants.SvDocumentId].IsNullOrEmpty() && eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>() > 0)
                        {
                            var manager = new DocumentManager();
                            DocumentMetaData documentMetaData = manager.GetDocumentMetaData(eventData.PropertyValues[EventPropertyConstants.SvDocumentId].Value <int>());
                            eventData.DocumentMetaData = documentMetaData;
                        }

                        //Check if this event notification is a communication event. If so, we need to call back to SV to get metadata about the communication
                        if (eventNotificationId >= 300 && eventNotificationId <= 399)
                        {
                            if (eventData.PropertyValues[EventPropertyConstants.AdditionalInfoId].IsNullOrEmpty() || eventData.PropertyValues[EventPropertyConstants.AdditionalInfoId].Value <int>() == 0)
                            {
                                throw new Exception("An AdditionalInfoId is needed to get the communication event meta data");
                            }
                            var manager = new CommunicationManager();
                            manager.GetAuthorizationForSV();
                            CommunicationActivityMetadata communicationActivityMetadata = manager.GetCommunicationActivityMetaData(eventData.PropertyValues[EventPropertyConstants.AdditionalInfoId].Value <int>()).Result;
                            eventData.CommunicationActivityMetadata = communicationActivityMetadata;
                        }

                        //Check if this event notification is a Scholarship Universe Event (700's). If so, we need to call back to SU to get the metadata
                        if (eventNotificationId >= 700 && eventNotificationId <= 799)
                        {
                            if (!eventData.PropertyValues[EventPropertyConstants.SuScholarshipAwardId].IsNullOrEmpty() && !eventData.PropertyValues[EventPropertyConstants.SuClientTermId].IsNullOrEmpty())
                            {
                                var manager = new ScholarshipManager();
                                AwardPostItemData awardPostItemData = manager.GetAwardPostItemData(
                                    eventData.PropertyValues[EventPropertyConstants.SuScholarshipAwardId].Value <int>(),
                                    eventData.PropertyValues[EventPropertyConstants.SuClientTermId].Value <int>());
                                eventData.AwardPostItemData = awardPostItemData;
                            }
                        }

                        // populate PropertyValues with all the values that have been gathered
                        eventData.PopulatePropertyValues();

                        //Now Send it to the correct handler
                        if (eventHandler.HandleMethod == "DatabaseCommandNonQuery")
                        {
                            DatabaseCommandNonQueryHandler(eventData, eventHandler.DbCommandFieldValue);
                        }
                        else if (eventHandler.HandleMethod == "DatabaseStoredProcedure")
                        {
                            DatabaseStoredProcedure(eventData, eventHandler.DbCommandFieldValue);
                        }
                        else if (eventHandler.HandleMethod == "DocumentRetrieval")
                        {
                            DocumentRetrievalHandler(eventData);
                        }
                        else if (eventHandler.HandleMethod == "DocumentRetrievalAndStoredProc")
                        {
                            DocumentRetrievalHandler(eventData);
                            DatabaseStoredProcedure(eventData, eventHandler.DbCommandFieldValue);
                        }
                        else if (eventHandler.HandleMethod == "DocumentRetrievalAndNonQuery")
                        {
                            DocumentRetrievalHandler(eventData);
                            DatabaseCommandNonQueryHandler(eventData, eventHandler.DbCommandFieldValue);
                        }
                        else if (eventHandler.HandleMethod == "FileStore")
                        {
                            FileStoreHandler(eventData);
                        }
                        else if (eventHandler.HandleMethod == "FileStoreAndDocumentRetrieval")
                        {
                            DocumentRetrievalHandler(eventData);
                            //SV-2383: Moving the File Store handler *after* the Document Retrieval Handler so that if the Doc handler fails, it won't log the same event on retry.
                            FileStoreHandler(eventData);
                        }
                        else if (eventHandler.HandleMethod == "AwardLetterPrint")
                        {
                            logger.Info("detect this is the AwardLetterPrint");
                            AwardLetterDocumentRetrievalHandler(eventData);
                        }
                        else if (eventHandler.HandleMethod == "BatchProcessingAwardLetterPrint")
                        {
                            logger.Info("detect this is the BatchProcessingAwardLetterPrint");
                            BatchProcessRetrievalHandler(ConfigConstants.AwardLetterPrintBatchType, eventHandler.BatchName, eventData);
                        }
                        else if (eventHandler.HandleMethod == "ApiIntegration")
                        {
                            ApiIntegrationsHandler(eventHandler.ApiEndpointName, eventData);
                        }
                        else if (eventHandler.HandleMethod == "PowerFAIDS")
                        {
                            PowerFaidsHandler(eventData);
                        }
                    }

                    //Update the received event with a processed date time
                    var eventId     = eventData.PropertyValues[EventPropertyConstants.Id].Value <string>();
                    var storedEvent = dbContext.ReceivedEvents.FirstOrDefault(x => x.Id == eventId);
                    if (storedEvent != null)
                    {
                        storedEvent.ProcessedDateTime = DateTime.UtcNow;
                        dbContext.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                //Log here any exceptions
                logger.ErrorFormat("DataService ProcessPostedEvent Error: {0}", ex);
                throw;
            }
        }
Esempio n. 15
0
        // Send the event individually
        private async Task SendSingleEventNotificationAsync(string teamId, EventNotificationData notification)
        {
            // Ideally this should send a single message with text and card, but because of message splitting,
            // such a message is split into two (text-only and card-only). As a workaround, we start a reply chain
            // with the text message, then send the card as a reply to this post.

            // Create the activity
            var activity = new Activity(ActivityTypes.Message)
            {
                Conversation = new ConversationAccount {
                    Id = teamId
                },
                AttachmentLayout = AttachmentLayoutTypes.Carousel,
                Text             = notification.GetMessage(),
                Summary          = Strings.MultipleEventsSummary,
                Attachments      = new List <Attachment> {
                    notification.GetCard()
                },
                Entities = new List <Entity> {
                    notification.GetMention()
                },
                ServiceUrl = notification.User.ServiceUrl,
            };

            // Add new entry to EventMessages collection for message type "preview" to track the status of message sent
            var eventMessage = new EventMessage
            {
                EventId      = notification.Event.Id,
                OccurrenceId = notification.Occurrence.Id,
                Activity     = activity,
                TenantId     = notification.User.TenantId,
                MessageType  = MessageType.Event,
                ExpireAt     = notification.Occurrence.GetLastAllowableTimeToSendNotification(),
            };

            eventMessage = await this.eventDataProvider.AddEventMessageAsync(eventMessage);

            // Send the message
            try
            {
                await eventMessage.SendAsync(this.connectorClientFactory);

                this.logProvider.LogInfo($"Event notifications sent to {teamId} for event {notification.Event.Id}");
            }
            catch (Exception ex)
            {
                this.logProvider.LogError($"Failed to send notifications to team {teamId}", ex, new Dictionary <string, string>
                {
                    { "EventId", eventMessage.EventId },
                    { "OccurrenceId", eventMessage.OccurrenceId },
                    { "TeamId", teamId },
                    { "LastAttemptTime", DateTimeOffset.UtcNow.ToString() },
                    { "LastAttemptStatusCode", eventMessage.MessageSendResult?.StatusCode.ToString() },
                    { "ResponseBody", eventMessage.MessageSendResult?.ResponseBody },
                });
                throw;
            }
            finally
            {
                // Record the result of the send
                await this.eventDataProvider.UpdateEventMessageAsync(eventMessage);
            }
        }