/// <summary> /// Process the publish message. /// </summary> /// <param name="message">BaseMessage instance.</param> public void ProcessMessage(BaseMessage message) { PublishMessage publishMessage = message as PublishMessage; try { this.Diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("begin publish {0}", message.FileId)); Repository repository = this.RepositoryService.GetRepositoryById(publishMessage.RepositoryId); // Read the config values this.MaxRetryCount = ConfigReader<int>.GetRepositoryConfigValues(repository.BaseRepository.Name, BaseQueueService.MaxRetry_Count); this.publishInterval = ConfigReader<int>.GetRepositoryConfigValues(repository.BaseRepository.Name, BaseQueueService.Publish_Interval); this.VerifyFileInterval = ConfigReader<int>.GetRepositoryConfigValues(repository.BaseRepository.Name, BaseQueueService.VerifyFile_Interval); this.FileService = this.fileServiceFactory.GetFileService(repository.BaseRepository.Name); string fileIdentifier = this.FileService.PublishFile(publishMessage); if (!string.IsNullOrEmpty(fileIdentifier)) { this.AddVerifyFileMessageToQueue(publishMessage); this.UpdateFileStatusAndDeleteFromQueue(publishMessage, fileIdentifier); } else { this.UpdateMessageInQueue(publishMessage, this.publishInterval); } this.Diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("Complete publish {0}", message.FileId)); } catch (WebException webException) { this.Diagnostics.WriteErrorTrace(TraceEventId.Exception, webException); HttpWebResponse httpResponse = (HttpWebResponse)webException.Response; HttpStatusCode statusCode = httpResponse.StatusCode; if (statusCode == HttpStatusCode.Unauthorized || statusCode == HttpStatusCode.NotFound) { this.UpdateFileStatusAsError(publishMessage); } else { this.UpdateMessageInQueue(publishMessage, this.publishInterval); } } catch (Exception exception) { this.Diagnostics.WriteErrorTrace(TraceEventId.Exception, exception); this.UpdateFileStatusAsError(publishMessage); } }
/// <summary> /// Processes VerifyFileMessage. /// </summary> /// <param name="message">BaseMessage instance.</param> public void ProcessMessage(BaseMessage message) { VerifyFileMessage verifyFileMessage = message as VerifyFileMessage; try { Repository repository = this.RepositoryService.GetRepositoryById(verifyFileMessage.RepositoryId); // Read the config values this.MaxRetryCount = ConfigReader<int>.GetRepositoryConfigValues(repository.BaseRepository.Name, BaseQueueService.MaxRetry_Count); this.VerifyFileInterval = ConfigReader<int>.GetRepositoryConfigValues(repository.BaseRepository.Name, BaseQueueService.VerifyFile_Interval); this.FileService = this.fileServiceFactory.GetFileService(repository.BaseRepository.Name); DM.File file = FileService.GetFileByFileId(verifyFileMessage.FileId); OperationStatus status = this.FileService.CheckIfFileExistsOnExternalRepository(verifyFileMessage); if (status.Succeeded) { this.blobDataRepository.DeleteFile(file.BlobId); this.UpdateFileAndDeleteFromQueue(verifyFileMessage); } else { this.UpdateMessageInQueue(verifyFileMessage, this.VerifyFileInterval); } } catch (WebException webException) { this.Diagnostics.WriteErrorTrace(TraceEventId.Exception, webException); HttpWebResponse httpResponse = (HttpWebResponse)webException.Response; HttpStatusCode statusCode = httpResponse.StatusCode; if (statusCode == HttpStatusCode.NotFound || statusCode == HttpStatusCode.RequestTimeout) { this.UpdateMessageInQueue(verifyFileMessage, this.VerifyFileInterval); } else { this.UpdateFileStatusAsError(verifyFileMessage); } } catch (Exception exception) { this.Diagnostics.WriteErrorTrace(TraceEventId.Exception, exception); this.UpdateFileStatusAsError(verifyFileMessage); } }
public void Allow_ProcessMessage() { this.deletedMessage = null; this.fileUpdated = false; VerifyFileMessage message = new VerifyFileMessage() { RepositoryId = 1, FileId = 1 }; IMessageHandler queueService = this.GetVerifyFileQueueService(); using (ShimsContext.Create()) { ShimConfigReader<int>.GetRepositoryConfigValuesStringString = (baseRepositoryName, SettingName) => { return 3; }; queueService.ProcessMessage(message); } Assert.IsTrue(this.deletedMessage == message); Assert.IsTrue(this.isDeletedFromBlob); Assert.IsTrue(this.file.Status == FileStatus.Posted.ToString()); }
public void Allow_ProcessMessage() { this.addedMessage = null; this.deletedMessage = null; this.fileUpdated = false; PublishMessage message = new PublishMessage() { RepositoryId = 1, FileId = 1 }; IMessageHandler publishQueueService = this.GetPublishQueueService(); using (ShimsContext.Create()) { ShimConfigReader<int>.GetRepositoryConfigValuesStringString = (baseRepositoryName, SettingName) => { return 3; }; publishQueueService.ProcessMessage(message); } Assert.IsTrue(this.deletedMessage == message); Assert.IsTrue(this.file.Status == FileStatus.Verifying.ToString()); var verifyFileMessage = this.addedMessage as VerifyFileMessage; Assert.IsNotNull(verifyFileMessage); }
/// <summary> /// Reuturns the PublishQueueServicer instance. /// </summary> /// <param name="nullMessageHandler">Indicates if the handler has to be returned or not.</param> /// <returns>MessaeRouter instance.</returns> private PublishQueueService GetPublishQueueService() { this.fileService = new StubIFileService() { PublishFilePublishMessage = (publishMessage) => { return "successfull"; }, GetFileByFileIdInt32 = (fileId) => { this.file = new File() { FileId = 1 }; return file; }, UpdateFileFile = (file) => { this.file = file; return true; }, }; this.fileServiceFactory = new StubIFileServiceFactory() { GetFileServiceString = (instanceName) => { return this.fileService; } }; this.repositoryService = new StubIRepositoryService() { GetRepositoryByIdInt32 = (repositoryId) => { return new Repository() { BaseRepository = new BaseRepository() { Name = "SkyDrive", BaseRepositoryId = 2 }, RepositoryId = 1, Name = "test" }; } }; this.queueRepository = new StubIQueueRepository() { AddMessageToQueueBaseMessage = (message) => { this.addedMessage = message; }, DeleteFromQueueBaseMessage = (message) => { this.deletedMessage = message; }, UpdateMessageBaseMessage = (message) => { this.updatedQueueContent = true; } }; PublishQueueService publishQueueService = new PublishQueueService(this.fileServiceFactory, this.repositoryService, this.queueRepository); return publishQueueService; }
public void Error_When_PublishFile_Throws_Exception_AND_Exceeds_Maximum_Retries() { this.addedMessage = null; this.deletedMessage = null; this.fileUpdated = false; int startCount = 0; PublishMessage message = new PublishMessage() { RepositoryId = 1, FileId = 1, RetryCount = startCount }; PublishQueueService publishQueueService = this.GetPublishQueueService(); this.fileService = new StubIFileService() { PublishFilePublishMessage = (publishMessage) => { throw new Exception("test"); }, GetFileByFileIdInt32 = (fileId) => { this.file = new File() { FileId = 1 }; return file; }, UpdateFileFile = (file) => { this.file = file; return true; }, }; using (ShimsContext.Create()) { ShimConfigReader<int>.GetRepositoryConfigValuesStringString = (baseRepositoryName, SettingName) => { return 3; }; publishQueueService.ProcessMessage(message); } Assert.IsTrue(this.file.Status == FileStatus.Error.ToString()); Assert.IsTrue(this.deletedMessage == message); }
/// <summary> /// Updates the retry count and updates the Message in the queue queue /// if the retry count is greater then the max retry count updates the file status as error and deletes the message from queue /// </summary> /// <param name="message">BaseMessage instance.</param> /// <param name="intervalInminutes">Interval In Minutes.</param> protected void UpdateMessageInQueue(BaseMessage message, int interval) { if (message.RetryCount < MaxRetryCount - 1) { message.RetryCount += 1; message.ProcessOn = DateTime.UtcNow.AddSeconds(interval); this.QueueRepository.UpdateMessage(message); this.Diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("Adding the message back to the queue, after exception. RetryCount: {0}", message.RetryCount)); } else { this.Diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("Exceeded Max no of allowed Retries: {0}", message.RetryCount)); UpdateFileStatusAsError(message); } }
/// <summary> /// Updates the file status as error. /// </summary> /// <param name="message">BaseMessage instance.</param> protected void UpdateFileStatusAsError(BaseMessage message) { File file = this.FileService.GetFileByFileId(message.FileId); file.RepositoryId = message.RepositoryId; file.ModifiedOn = DateTime.UtcNow; file.Status = FileStatus.Error.ToString(); this.FileService.UpdateFile(file); this.QueueRepository.DeleteFromQueue(message); }
public void Error_When_CheckIfFileExistsOnExternalRepository_Returns_Failure_AND_Exceeds_Maximum_Retries() { this.deletedMessage = null; this.fileUpdated = false; int startCount = 2; VerifyFileMessage message = new VerifyFileMessage() { RepositoryId = 1, FileId = 1, RetryCount = startCount }; VerifyFileQueueService queueService = this.GetVerifyFileQueueService(); this.fileService = new StubIFileService() { CheckIfFileExistsOnExternalRepositoryVerifyFileMessage = (verifyMessage) => { return OperationStatus.CreateFailureStatus(string.Empty); }, GetFileByFileIdInt32 = (fileId) => { this.file = new File() { FileId = 1 }; return file; }, UpdateFileFile = (file) => { this.file = file; return true; }, }; using (ShimsContext.Create()) { ShimConfigReader<int>.GetRepositoryConfigValuesStringString = (baseRepositoryName, SettingName) => { return 3; }; queueService.ProcessMessage(message); } Assert.IsTrue(this.file.Status == FileStatus.Error.ToString()); Assert.IsTrue(this.deletedMessage == message); Assert.IsFalse(this.isDeletedFromBlob); }
/// <summary> /// Posts the message in the queue. /// </summary> /// <param name="message">BaseMessage instance.</param> public void PostFileToQueue(BaseMessage message) { message.ProcessOn = DateTime.UtcNow; this.QueueRepository.AddMessageToQueue(message); }
/// <summary> /// Ads the message to queue asynchronously. /// </summary> /// <param name="message">BaseMessage instance.</param> /// <returns>Task instance.</returns> public Task<bool> AddMessageToQueueAsync(BaseMessage message) { CloudQueueMessage cloudMessage = new CloudQueueMessage(this.Serialize(message)); var tcs = new TaskCompletionSource<bool>(); this.queue.BeginAddMessage( cloudMessage, ar => { try { this.queue.EndAddMessage(ar); tcs.SetResult(true); } catch (Exception exception) { tcs.SetException(exception); } }, null); return tcs.Task; }
/// <summary> /// Adds the message to queue. /// </summary> /// <param name="message">BaseMessage instance.</param> public void AddMessageToQueue(BaseMessage message) { CloudQueueMessage cloudMessage = new CloudQueueMessage(this.Serialize(message)); this.queue.AddMessage(cloudMessage); }
/// <summary> /// Serializes the BaseMessage. /// </summary> /// <param name="message">BaseMessage instance.</param> /// <returns>Message data as string.</returns> private string Serialize(BaseMessage message) { string messageData = null; DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(BaseMessage), GetKnownTypes()); using (MemoryStream ms = new MemoryStream()) { dataContractJsonSerializer.WriteObject(ms, message); messageData = Encoding.Default.GetString(ms.ToArray()); } return messageData; }
/// <summary> /// Updates the message content in the queue. /// </summary> /// <param name="message">BaseMessage instance.</param> public void UpdateMessage(BaseMessage message) { CloudQueueMessage cloudMessage = message.CloudMessage; cloudMessage.SetMessageContent(this.Serialize(message)); this.queue.UpdateMessage(cloudMessage, TimeSpan.FromSeconds(0.0), MessageUpdateFields.Content | MessageUpdateFields.Visibility); }
/// <summary> /// Deletes the message from the queue. /// </summary> /// <param name="message">BaseMessage instance.</param> public void DeleteFromQueue(BaseMessage message) { this.queue.DeleteMessage(message.CloudMessage); }
/// <summary> /// Reuturns the VerifyFileQueueService instance. /// </summary> /// <returns>VerifyFileQueueService instance.</returns> private VerifyFileQueueService GetVerifyFileQueueService() { this.fileService = new StubIFileService() { CheckIfFileExistsOnExternalRepositoryVerifyFileMessage = (message) => { return OperationStatus.CreateSuccessStatus(); }, GetFileByFileIdInt32 = (fileId) => { this.file = new File() { FileId = 1 }; return file; }, UpdateFileFile = (file) => { this.file = file; return true; }, }; this.fileServiceFactory = new StubIFileServiceFactory() { GetFileServiceString = (instanceName) => { return this.fileService; } }; this.repositoryService = new StubIRepositoryService() { GetRepositoryByIdInt32 = (repositoryId) => { return new Repository() { BaseRepository = new BaseRepository() { Name = "SkyDrive", BaseRepositoryId = 2 }, RepositoryId = 1, Name = "test" }; } }; this.queueRepository = new StubIQueueRepository() { DeleteFromQueueBaseMessage = (message) => { this.deletedMessage = message; }, UpdateMessageBaseMessage = (message) => { this.updatedQueueContent = true; } }; this.blobRepository = new StubIBlobDataRepository() { DeleteFileString = (filename) => { this.isDeletedFromBlob = true; return this.isDeletedFromBlob; } }; VerifyFileQueueService queueService = new VerifyFileQueueService(this.fileServiceFactory, this.repositoryService, this.queueRepository, this.blobRepository); return queueService; }
public void Retry_When_PublishFile_Returns_Null() { this.addedMessage = null; this.deletedMessage = null; this.fileUpdated = false; int startCount = 1; PublishMessage message = new PublishMessage() { RepositoryId = 1, FileId = 1, RetryCount = startCount }; PublishQueueService publishQueueService = this.GetPublishQueueService(); this.fileService = new StubIFileService() { PublishFilePublishMessage = (publishMessage) => { return string.Empty; } }; this.fileService = new StubIFileService() { PublishFilePublishMessage = (publishMessage) => { return null; } }; using (ShimsContext.Create()) { ShimConfigReader<int>.GetRepositoryConfigValuesStringString = (baseRepositoryName, SettingName) => { return 3; }; publishQueueService.ProcessMessage(message); } Assert.IsTrue(message.RetryCount == startCount+1); Assert.IsTrue(updatedQueueContent); Assert.IsNull(this.deletedMessage); }
/// <summary> /// Instantiates the message handler and calls the ProcessMessage method. /// </summary> /// <param name="baseMessage">BaseMessage instance.</param> private void RouteMessage(BaseMessage baseMessage) { try { // do not process the message if the ProcessOn date time is less then the current time. if (baseMessage.ProcessOn > DateTime.UtcNow) { diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("message not procesed ProcessOntime {0} currentUTCTime {1}", baseMessage.ProcessOn.ToString(), DateTime.UtcNow.ToString())); return; } IMessageHandler messageHandler = null; messageHandler = this.messageHandlerFactory.GetMessageHandler(baseMessage.MessageHandler); if (messageHandler == null) { diagnostics.WriteInformationTrace(TraceEventId.Flow, string.Format("Message Handler not found FileId:{0} RepositoryId {1}", baseMessage.FileId, baseMessage.RepositoryId)); return; } messageHandler.ProcessMessage(baseMessage); } catch (Exception exception) { diagnostics.WriteErrorTrace(TraceEventId.Exception, exception); } }