public ActionResult Publish(TemplatePublisherModel templatePublisher, HttpPostedFileBase file, string tenantId) { CloudBlockBlob originalFileBlob = null; PublishModel publishJob = new PublishModel(); try { if (file == null) { ModelState.AddModelError(string.Empty, "Please provide file path"); } //create an instance of templateModel from inputs IEnumerable <TemplateModel> templatesFromStorage = TemplateModel.GetFromStorage(tenantId); templatePublisher.Template = templatesFromStorage.Single <TemplateModel>(x => string.Compare(x.TemplateId, templatePublisher.Template.TemplateId, StringComparison.OrdinalIgnoreCase) == 0); publishJob.TenantId = tenantId; publishJob.OriginalFileName = file.FileName; publishJob.TemplateId = templatePublisher.Template.TemplateId; publishJob.OriginalFileSizeInBytes = file.ContentLength; publishJob.SaveToStorage(); originalFileBlob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(publishJob.OriginalFileBlobRef); // Create the blob by uploading the original file. using (var fileStream = file.InputStream) { originalFileBlob.UploadFromStream(fileStream); } //Create a command message for the worker role and send it by queue RmsCommand rmsCommand = new RmsCommand(RmsCommand.Command.PublishTemplate, tenantId, publishJob.OriginalFileBlobRef); CloudQueueMessage cloudQueueMessage = new CloudQueueMessage(rmsCommand.ToString()); DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.AddMessage(cloudQueueMessage); //Poll for completion of job by worker role. Don't poll for more than a minute DateTime startTime = DateTime.Now; PublishModel pJob = publishJob; while (startTime.AddMinutes(1) > DateTime.Now && string.Compare(pJob.JState.ToString(), DataModel.Models.PublishModel.JobState.Completed.ToString(), true) != 0) { System.Threading.Thread.Sleep(1 * 100); pJob = DataModel.Models.PublishModel.GetFromStorage(publishJob.TenantId, publishJob.OriginalFileBlobRef); } //send the published file to the user CloudBlockBlob publishedFileblob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(pJob.PublishedFileBlobRef); return(File(publishedFileblob.OpenRead(), "application/force-download", pJob.PublishedFileName)); } catch (Exception ex) { Trace.TraceError(ex.Message); return(View("Error")); } }
private void ProcessQueueMessage(object state) { CloudQueueMessage msg = state as CloudQueueMessage; try { // Log and delete if this is a "poison" queue message (repeatedly processed // and always causes an error that prevents processing from completing). // Production applications should move the "poison" message to a "dead message" // queue for analysis rather than deleting the message. if (msg.DequeueCount > 5) { Trace.TraceError("Deleting poison message: message {0} Role Instance {1}.", msg.ToString(), GetRoleInstance()); DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.DeleteMessage(msg); return; } RmsCommand rmsCommand = new RmsCommand(msg.AsString); switch (rmsCommand.RmsOperationCommand) { case RmsCommand.Command.GetTemplate: { ServicePrincipalModel sp = ServicePrincipalModel.GetFromStorage(rmsCommand.Parameters.First <object>().ToString()); RMS.RmsContentPublisher rmsPublisher = RMS.RmsContentPublisher.Create(sp.TenantId, sp.AppId, sp.Key); var templates = rmsPublisher.GetRmsTemplates(); List <TemplateModel> templateEntityList = new List <TemplateModel>(); foreach (var temp in templates) { TemplateModel templateEntity = new TemplateModel(); templateEntity.TenantId = sp.TenantId; templateEntity.TemplateId = temp.TemplateId; templateEntity.TemplateName = temp.Name; templateEntity.TemplateDescription = temp.Description; templateEntityList.Add(templateEntity); } TemplateModel.SaveToStorage(templateEntityList); break; } case RmsCommand.Command.PublishTemplate: { PublishModel publishJob = PublishModel.GetFromStorage(rmsCommand.Parameters[0].ToString(), rmsCommand.Parameters[1].ToString()); ServicePrincipalModel sp = ServicePrincipalModel.GetFromStorage(rmsCommand.Parameters[0].ToString()); CloudBlockBlob originalFileBlob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(publishJob.OriginalFileBlobRef); Stream sinkStream = null; string tempFilePath = null; try { //if file length is less than 100,000 bytes, keep it in memory if (publishJob.OriginalFileSizeInBytes < 100000) { sinkStream = new MemoryStream(); } else { tempFilePath = Path.GetRandomFileName(); sinkStream = new FileStream(tempFilePath, FileMode.Create); } using (Stream sourceStream = originalFileBlob.OpenRead()) using (sinkStream) { RMS.RmsContent rmsContent = new RMS.RmsContent(sourceStream, sinkStream); rmsContent.RmsTemplateId = publishJob.TemplateId; rmsContent.OriginalFileNameWithExtension = publishJob.OriginalFileName; RMS.RmsContentPublisher rmsContentPublisher = RMS.RmsContentPublisher.Create(sp.TenantId, sp.AppId, sp.Key); rmsContentPublisher.PublishContent(rmsContent); publishJob.PublishedFileName = rmsContent.PublishedFileNameWithExtension; sinkStream.Flush(); sinkStream.Seek(0, SeekOrigin.Begin); //published file is uploaded to blob storage. //Note: This sample code doesn't manage lifetime of this original and published file blob //Actual code must manage the lifetime as appropriate CloudBlockBlob destFileBlob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(publishJob.PublishedFileBlobRef); using (CloudBlobStream blobStream = destFileBlob.OpenWrite()) { int tempSize = 1024; byte[] tempBuffer = new byte[tempSize]; while (true) { int readSize = sinkStream.Read(tempBuffer, 0, tempSize); if (readSize <= 0) { break; } blobStream.Write(tempBuffer, 0, readSize); } blobStream.Flush(); } } publishJob.JState = PublishModel.JobState.Completed.ToString(); publishJob.SaveToStorage(); break; } finally { if (!string.IsNullOrWhiteSpace(tempFilePath) && File.Exists(tempFilePath)) { File.Delete(tempFilePath); } } } } //delete the message from the queue DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.DeleteMessage(msg); } catch (Exception ex) { Process p = Process.GetCurrentProcess(); string a = p.ProcessName; string b = p.MainModule.FileName; string err = ex.Message; if (ex.InnerException != null) { err += " Inner Exception: " + ex.InnerException.Message; } if (msg != null) { err += " Last queue message retrieved: " + msg.AsString; } Trace.TraceError(err); } }