private void ParseJobXml(ref DigitalSendServerJobLogger log, string xmlJobInfo) { if (!string.IsNullOrEmpty(xmlJobInfo)) { ParseJobXml(ref log, XmlUtil.CreateXDocument(xmlJobInfo)); } }
/// <summary> /// Checks to make sure we have a valid SessionId before attempting to log. /// </summary> /// <param name="log">The DigitalSendServerJobLogger.</param> private void SubmitLog(DigitalSendServerJobLogger log) { if (log.SessionId.Length != 8) { TraceFactory.Logger.Error($"Invalid Session Id: {log.SessionId}. FileName: {log.FileName}."); return; } _dataLogger.SubmitAsync(log); }
private DigitalSendServerJobLogger CreateLogFromDevice(IDataRecord reader) { DigitalSendServerJobLogger log = new DigitalSendServerJobLogger((Guid)reader["Id"]); log.JobType = reader["JobType"] as string; log.FileName = GetFileName(reader); log.FileSizeBytes = reader["DeliveredFileSize"] as int?; ParseJobXml(ref log, reader["XmlJobInfo"] as string); log.CompletionDateTime = ApplyLocalOffset((DateTime)reader["CompletionTime"], log.DssVersion); // Figure out the session ID log.SessionId = GetSessionId(reader); return(log); }
private DigitalSendServerJobLogger CreateLogForNotFound(Guid jobId, string logText) { DigitalSendServerJobLogger log = new DigitalSendServerJobLogger(jobId); log.CompletionDateTime = DateTime.Now; log.JobType = logText; log.CompletionStatus = logText; log.FileName = logText; log.FileType = logText; log.DssVersion = logText; log.ProcessedBy = logText; log.DeviceModel = logText; // Use the last session ID we logged log.SessionId = _sessionId; return(log); }
private DigitalSendServerJobLogger CreateLogFromMaster(IDataRecord reader) { DigitalSendServerJobLogger log = new DigitalSendServerJobLogger((Guid)reader["JobId"]); log.JobType = reader["JobType"] as string; log.DssVersion = reader["DssSoftwareVersion"] as string; log.CompletionDateTime = ApplyLocalOffset((DateTime)reader["CompletionTime"], log.DssVersion); log.CompletionStatus = reader["JobCompletionStatus"] as string; log.FileName = GetFileName(reader); log.FileSizeBytes = reader["DeliveredFileSize"] as int?; log.FileType = reader["FileType"] as string; log.ScannedPages = (short?)(reader["ScannedPages"] as int?); log.ProcessedBy = reader["ProcessedBy"] as string; log.DeviceModel = reader["DeviceModel"] as string; // Figure out the session ID log.SessionId = GetSessionId(reader); return(log); }
/// <summary> /// The XML data received from the device table seems to be inconsistent at best. /// For the purpose of populating the server log, we'll populate what we can, /// ignoring all errors that may be thrown while attempting to retrieve the data, /// marking them as "unavailable" as a flag that an attempt was made to retrieve the data. /// </summary> /// <param name="log"></param> /// <param name="xmlJobInfo"></param> private void ParseJobXml(ref DigitalSendServerJobLogger log, XDocument xmlJobInfo) { string unavailable = "<unavailable>"; StringBuilder message = null; XElement headerElement = xmlJobInfo.Descendants("HeaderElements").FirstOrDefault(); if (headerElement != null) { try { log.DeviceModel = headerElement.Element("cDeviceDescription").Value; } catch { log.DeviceModel = unavailable; } try { log.CompletionStatus = headerElement.Element("cJobStatusAppHeading").Value; } catch { log.CompletionStatus = unavailable; } } else { message = new StringBuilder("HeaderElements "); } XElement detailsElement = xmlJobInfo.Descendants("JobLogDetails").FirstOrDefault(); if (detailsElement != null) { try { log.FileType = detailsElement.Element("cFileType").Value; } catch { log.FileType = unavailable; } try { log.ScannedPages = short.Parse(detailsElement.Element("cPagesScanned").Value); } catch { } //Just move on try { log.DssVersion = detailsElement.Element("cDssSoftwareVersionColon").Value; } catch { log.DssVersion = unavailable; } try { log.ProcessedBy = detailsElement.Element("cJobProcessedBy").Value; } catch { log.ProcessedBy = unavailable; } } else { if (message == null) { message = new StringBuilder(); } message.Append("JobLogDetails "); } //Check to see if any data was not logged because of null elements if (message != null) { message.Append("elements not found."); message.Append(xmlJobInfo.ToString()); TraceFactory.Logger.Debug(message.ToString()); } }
/// <summary> /// Gets the data for each job ID and logs it /// </summary> private void LogData(SqlAdapter adapter, DSSJobLogTable logTable, string sqlText, ref List <Guid> jobIds) { TraceFactory.Logger.Debug("Processing {0}.".FormatWith(logTable.ToString())); DbDataReader jobsReader = null; Retry.WhileThrowing(() => { jobsReader = adapter.ExecuteReader(sqlText); }, 3, TimeSpan.FromSeconds(5), _retryExceptions); try { bool continueRead = true; while (continueRead) { try { continueRead = jobsReader.Read(); } catch (SqlException sqlEx) { if (sqlEx.Number == 1205) { TraceFactory.Logger.Debug("Deadlock encountered. Continue to process."); } else { TraceFactory.Logger.Error(sqlEx); //Unexpected SQL exception. } continue; //Skip to the next record } if (continueRead) { // Successful read. Log the entry DigitalSendServerJobLogger log = null; switch (logTable) { case DSSJobLogTable.JobLogDevice: log = CreateLogFromDevice(jobsReader); break; case DSSJobLogTable.JobLogMaster: log = CreateLogFromMaster(jobsReader); break; } SubmitLog(log); TraceFactory.Logger.Debug("Found job with ID " + log.DigitalSendJobId.ToString()); //Job successfully logged. Remove it from the list jobIds.Remove(log.DigitalSendJobId); // See if we've found a new session ID if (log.SessionId != _sessionId) { _sessionId = log.SessionId; if (RetrievedSession != null) { RetrievedSession(this, new SessionEventArgs(log.SessionId)); } } } } } finally { if (jobsReader != null) { jobsReader.Close(); jobsReader.Dispose(); } } }
/// <summary> /// Retrieves the job records from the DSS database. /// For the records that are not found in the database, the following may be logged to the data logger: /// unavailable - The job ID was found in the DSS database, and partial data was retrieved for the job. Represents job data that could not be retrieved. /// unknown - While attempting to find the job ID in the database, a database error occurred, and after retrying the operation several times, processing moved on. /// missing - The job was not found in either the Master or the Device table. /// </summary> public void RetrieveRecords() { TraceFactory.Logger.Debug("Retrieving Job IDs from STFTransactionLog table."); using (SqlAdapter adapter = new SqlAdapter(_connectionString)) { List <Guid> jobIds = new List <Guid>(); //List of records that have been updated try { using (DbDataReader idsReader = adapter.ExecuteReader(Resource.TransactionRetrieveSql)) { while (idsReader.Read()) { jobIds.Add((Guid)idsReader["JobId"]); } idsReader.Close(); } } catch (SqlException sqlEx) { TraceFactory.Logger.Error("Error retrieving list of Job IDs. Aborting.", sqlEx); return; } TraceFactory.Logger.Debug("Found {0} records.".FormatWith(jobIds.Count)); if (jobIds.Any()) { // Capture list of job IDs now while we have the entire list, to be used to cleanup the transaction table later. string jobIdList = "'" + string.Join("','", jobIds) + "'"; string notFoundText = "<missing>"; try { //Log data from JobLogMaster. LogData(adapter, DSSJobLogTable.JobLogMaster, Resource.JobLogMasterSql.FormatWith(jobIdList), ref jobIds); } catch (SqlException sqlEx) { TraceFactory.Logger.Error("Unable to process JobLogMaster.", sqlEx); notFoundText = "<unknown>"; } //Check to see if there were any jobs that weren't processed if (jobIds.Any()) { // Recreate list of job IDs, since some of the jobs have already been processed and removed from jobIds string unprocessedJobIdList = "'" + string.Join("','", jobIds) + "'"; try { //Log data from JobLogDevice. LogData(adapter, DSSJobLogTable.JobLogDevice, Resource.JobLogDeviceSql.FormatWith(unprocessedJobIdList), ref jobIds); } catch (SqlException sqlEx) { TraceFactory.Logger.Error("Unable to process JobLogDevice.", sqlEx); notFoundText = "<unknown>"; } } // Any job Ids left over at this point were not found in either the master nor the device tables // Log an entry in the data log to flag data that was not found. foreach (Guid jobId in jobIds) { DigitalSendServerJobLogger log = CreateLogForNotFound(jobId, notFoundText); SubmitLog(log); } //At this point, all jobs Ids have been processed jobIds.Clear(); //Remove the JobIds from the transaction table. string sql = Resource.TransactionCleanupSql.FormatWith(jobIdList); //TraceFactory.Logger.Debug(sql); Retry.WhileThrowing(() => { adapter.ExecuteNonQuery(sql); }, 5, TimeSpan.FromSeconds(5), _retryExceptions); } } }