예제 #1
0
        public void SubmitImageForProcessing(String clientId, Guid requestId, Uri imageLibraryUri, String originalLocation, Byte tileSize, Byte slices, byte[] imgBytes)
        {
            Uri           imageUri      = null;
            BlobAccessor  blobAccessor  = null;
            TableAccessor tableAccessor = null;

            try
            {
                String connString = new StorageBrokerInternal().GetStorageConnectionStringForClient(clientId);
                tableAccessor = new TableAccessor(connString);
                blobAccessor  = new BlobAccessor(connString);

                imageUri = blobAccessor.StoreImage(imgBytes, BlobAccessor.ImageInputContainer, requestId.ToString());
                var job = tableAccessor.CreateJob(clientId,
                                                  requestId,
                                                  originalLocation,
                                                  imageUri,
                                                  Utilities.ImageUtilities.GetImageSize(imgBytes),
                                                  tileSize,
                                                  slices);

                if (QueueAccessor.IsAvailable)
                {
                    QueueAccessor.ImageRequestQueue.SubmitMessage <ImageRequestMessage>
                        (clientId, requestId, imageUri, imageLibraryUri, tileSize, slices);

                    tableAccessor.WriteStatusEntry(requestId,
                                                   String.Format("New request from {0}: {1}", clientId, originalLocation));

                    try
                    {
                        Notifier.SendRequestStartedNotification(
                            clientId,
                            requestId,
                            originalLocation,
                            imageUri,
                            tileSize,
                            job.StartTime);
                    }
                    catch (Exception e)
                    {
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                           requestId,
                                           e.GetType(),
                                           e.Message,
                                           e.StackTrace,
                                           Environment.NewLine);
                    }
                }
                else
                {
                    throw new SystemException("Application queueing service could not be initialized; request cannot be processed");
                }
            }
            catch (Exception e)
            {
                // clean up if there was a problem
                if (blobAccessor != null)
                {
                    blobAccessor.DeleteImage(imageUri);
                }

                Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                 requestId,
                                 e.GetType(),
                                 e.Message,
                                 e.StackTrace,
                                 Environment.NewLine);

                // surface exception to client
                throw;
            }
        }
예제 #2
0
        public void SubmitImageForProcessing(String clientId, Guid requestId, Uri imageLibraryUri, String originalLocation, Byte tileSize, Byte slices, byte[] imgBytes)
        {
            Uri imageUri = null;
            BlobAccessor blobAccessor = null;
            TableAccessor tableAccessor = null;

            try
            {
                String connString = new StorageBrokerInternal().GetStorageConnectionStringForClient(clientId);
                tableAccessor = new TableAccessor(connString);
                blobAccessor = new BlobAccessor(connString);

                imageUri = blobAccessor.StoreImage(imgBytes, BlobAccessor.ImageInputContainer, requestId.ToString());
                var job = tableAccessor.CreateJob(clientId,
                                                    requestId,
                                                    originalLocation,
                                                    imageUri,
                                                    Utilities.ImageUtilities.GetImageSize(imgBytes),
                                                    tileSize,
                                                    slices);

                if (QueueAccessor.IsAvailable)
                {
                    QueueAccessor.ImageRequestQueue.SubmitMessage<ImageRequestMessage>
                            (clientId, requestId, imageUri, imageLibraryUri, tileSize, slices);

                    tableAccessor.WriteStatusEntry(requestId,
                        String.Format("New request from {0}: {1}", clientId, originalLocation));

                    try
                    {
                        Notifier.SendRequestStartedNotification(
                            clientId,
                            requestId,
                            originalLocation,
                            imageUri,
                            tileSize,
                            job.StartTime);
                    }
                    catch (Exception e)
                    {
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                            requestId,
                            e.GetType(),
                            e.Message,
                            e.StackTrace,
                            Environment.NewLine);
                    }
                }
                else
                {
                    throw new SystemException("Application queueing service could not be initialized; request cannot be processed");
                }
            }
            catch (Exception e)
            {
                // clean up if there was a problem
                if (blobAccessor != null) blobAccessor.DeleteImage(imageUri);

                Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                            requestId,
                                            e.GetType(),
                                            e.Message,
                                            e.StackTrace,
                                            Environment.NewLine);

                // surface exception to client
                throw;
            }
        }
예제 #3
0
        public override void Run()
        {
            TableAccessor tableAccessor = null;
            BlobAccessor blobAccessor = null;

            while (true)
            {
                #region NEW IMAGE REQUEST
                var requestMsg = QueueAccessor.IsAvailable ? QueueAccessor.ImageRequestQueue.AcceptMessage<ImageRequestMessage>() : null;
                if (requestMsg != null)
                {
                    // check for possible poison message
                    if (requestMsg.RawMessage.DequeueCount <= requestMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(requestMsg.ImageUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(requestMsg.ClientId));

                            // retrieve source image from blob storage
                            var imageBytes = blobAccessor.RetrieveImage(requestMsg.ImageUri);

                            // actual slices may be less than request if image is too small
                            var slices = ImageUtilities.SliceAndDice(imageBytes, requestMsg.Slices).ToList();
                            Byte totalSlices = (Byte)slices.Count;
                            if (requestMsg.Slices != totalSlices)
                            {
                                var job = tableAccessor.GetJobByRequestId(requestMsg.RequestId);
                                if (job != null)
                                {
                                    job.Slices = totalSlices;
                                    tableAccessor.UpdateJob(job);
                                }
                            }

                            // loop through each slice, storing it and submitting a message to queue
                            for (Byte sliceNum = 0; sliceNum < totalSlices; sliceNum++)
                            {
                                Uri slicePath = blobAccessor.StoreImage(
                                    slices[sliceNum], BlobAccessor.SliceInputContainer, String.Format("{0}_{1:000}", requestMsg.BlobName, sliceNum));

                                QueueAccessor.SliceRequestQueue.SubmitMessage<SliceRequestMessage>
                                    (requestMsg.ClientId, requestMsg.RequestId, requestMsg.ImageLibraryUri, slicePath, sliceNum, requestMsg.TileSize);

                                tableAccessor.WriteStatusEntry(requestMsg.RequestId,
                                    String.Format("Dispatched slice {0} of {1}", sliceNum, totalSlices - 1));
                            }

                            // message processed successfully
                            requestMsg.DeleteFromQueue();
                        }
                        catch (Exception e)
                        {
                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                requestMsg.RequestId,
                                e.GetType(),
                                e.Message,
                                e.StackTrace,
                                Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison message from the queue
                        requestMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                requestMsg.RequestId,
                                "N/A",
                                String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                    requestMsg.RawMessage.Id,
                                    QueueAccessor.ImageRequestQueue,
                                    QueueAccessor.ImageRequestQueue.PoisonThreshold),
                                "N/A",
                                Environment.NewLine);
                    }
                }
                #endregion

                #region COMPLETED SLICE NOTIFICATION
                var responseMsg = QueueAccessor.IsAvailable ? QueueAccessor.SliceResponseQueue.AcceptMessage<SliceResponseMessage>() : null;
                if (responseMsg != null)
                {
                    // check for possible poison message
                    if (responseMsg.RawMessage.DequeueCount <= responseMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(responseMsg.SliceUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(responseMsg.ClientId));

                            // get the job data (from Azure table) indicating number of slices and the tile size
                            var job = tableAccessor.GetJobByRequestId(responseMsg.RequestId);
                            if ((job != null) && (job.Slices > 0) && (job.TileSize > 0) && (job.SourceWidth > 0) && (job.SourceHeight > 0))
                            {
                                // get slices processed so far
                                var processedSliceUris = blobAccessor.RetrieveImageUris(BlobAccessor.SliceOutputContainer, responseMsg.BlobName).ToList();

                                // if we have the expected number, this is the last slice to complete
                                if (processedSliceUris.Count() == (Int32)job.Slices)
                                {
                                    Byte[] finalImgBytes = ImageUtilities.StitchAndMend(
                                        processedSliceUris, blobAccessor.RetrieveImages,
                                        (byte)job.TileSize, new Size(job.SourceWidth, job.SourceHeight));

                                    Uri finalImageUri = blobAccessor.StoreImage(finalImgBytes, BlobAccessor.ImageOutputContainer, responseMsg.BlobName);

                                    QueueAccessor.ImageResponseQueue.SubmitMessage<ImageResponseMessage>
                                        (responseMsg.ClientId, responseMsg.RequestId, finalImageUri);
                                }
                            }
                            else
                            {
                                throw new SystemException("Metadata for job {0} in Jobs table was not found or is invalid");
                            }

                            // message processed successfully
                            responseMsg.DeleteFromQueue();
                        }
                        catch (Exception e)
                        {

                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                responseMsg.RequestId,
                                e.GetType(),
                                e.Message,
                                e.StackTrace,
                                Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison message from the queue
                        responseMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                responseMsg.RequestId,
                                "N/A",
                                String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                    responseMsg.RawMessage.Id,
                                    QueueAccessor.SliceResponseQueue,
                                    QueueAccessor.SliceResponseQueue.PoisonThreshold),
                                "N/A",
                                Environment.NewLine);
                    }
                }
                #endregion

                #region MOST SINCERELY DONE NOTIFICATION
                var completeMsg = QueueAccessor.IsAvailable ? QueueAccessor.ImageResponseQueue.AcceptMessage<ImageResponseMessage>() : null;
                if (completeMsg != null)
                {
                    // check for possible poison message
                    if (completeMsg.RawMessage.DequeueCount <= completeMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(completeMsg.ImageUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(completeMsg.ClientId));

                            // get the completed job entity from table storage
                            var job = tableAccessor.GetJobByRequestId(completeMsg.RequestId);
                            if (job != null)
                            {

                                // update pointer to completed image (and the finish time)
                                job.FinalImageUri = completeMsg.ImageUri.ToString();
                                job.FinishTime = DateTime.UtcNow;

                                tableAccessor.UpdateJob(job);

                                tableAccessor.WriteStatusEntry(completeMsg.RequestId, "Request complete.");
                            }
                            else
                            {
                                Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                    completeMsg.RequestId,
                                    "N/A",
                                    "Request completed, but record not found in Jobs table",
                                    "N/A",
                                    Environment.NewLine);
                            }

                            // only notify user (or try to) once!
                            if (completeMsg.RawMessage.DequeueCount == 1)
                            {
                                try
                                {
                                    // notify via service bus that request is complete
                                    if (job != null)
                                    {
                                        Notifier.SendRequestCompletedNotification(
                                            job.ClientId,
                                            completeMsg.RequestId,
                                            completeMsg.ImageUri);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                        completeMsg.RequestId,
                                        e.GetType(),
                                        e.Message,
                                        e.StackTrace,
                                        Environment.NewLine);
                                }
                            }

                            // message processed successfully
                            completeMsg.DeleteFromQueue();
                        }

                        catch (Exception e)
                        {
                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                completeMsg.RequestId,
                                e.GetType(),
                                e.Message,
                                e.StackTrace,
                                Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison m essage from the queue
                        completeMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                completeMsg.RequestId,
                                "N/A",
                                String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                    completeMsg.RawMessage.Id,
                                    QueueAccessor.ImageResponseQueue,
                                    QueueAccessor.ImageResponseQueue.PoisonThreshold),
                                "N/A",
                                Environment.NewLine);
                    }
                }
                #endregion

                // only sleep if we didn't do anything this time through
                if ((requestMsg == null) && (responseMsg == null) && (completeMsg == null))
                {
                    Thread.Sleep(10000);
                }
            }
        }
예제 #4
0
        public override void Run()
        {
            TableAccessor tableAccessor = null;
            BlobAccessor  blobAccessor  = null;

            while (true)
            {
                #region NEW IMAGE REQUEST
                var requestMsg = QueueAccessor.IsAvailable ? QueueAccessor.ImageRequestQueue.AcceptMessage <ImageRequestMessage>() : null;
                if (requestMsg != null)
                {
                    // check for possible poison message
                    if (requestMsg.RawMessage.DequeueCount <= requestMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor  = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(requestMsg.ImageUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(requestMsg.ClientId));

                            // retrieve source image from blob storage
                            var imageBytes = blobAccessor.RetrieveImage(requestMsg.ImageUri);

                            // actual slices may be less than request if image is too small
                            var  slices      = ImageUtilities.SliceAndDice(imageBytes, requestMsg.Slices).ToList();
                            Byte totalSlices = (Byte)slices.Count;
                            if (requestMsg.Slices != totalSlices)
                            {
                                var job = tableAccessor.GetJobByRequestId(requestMsg.RequestId);
                                if (job != null)
                                {
                                    job.Slices = totalSlices;
                                    tableAccessor.UpdateJob(job);
                                }
                            }

                            // loop through each slice, storing it and submitting a message to queue
                            for (Byte sliceNum = 0; sliceNum < totalSlices; sliceNum++)
                            {
                                Uri slicePath = blobAccessor.StoreImage(
                                    slices[sliceNum], BlobAccessor.SliceInputContainer, String.Format("{0}_{1:000}", requestMsg.BlobName, sliceNum));

                                QueueAccessor.SliceRequestQueue.SubmitMessage <SliceRequestMessage>
                                    (requestMsg.ClientId, requestMsg.RequestId, requestMsg.ImageLibraryUri, slicePath, sliceNum, requestMsg.TileSize);

                                tableAccessor.WriteStatusEntry(requestMsg.RequestId,
                                                               String.Format("Dispatched slice {0} of {1}", sliceNum, totalSlices - 1));
                            }

                            // message processed successfully
                            requestMsg.DeleteFromQueue();
                        }
                        catch (Exception e)
                        {
                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                             requestMsg.RequestId,
                                             e.GetType(),
                                             e.Message,
                                             e.StackTrace,
                                             Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison message from the queue
                        requestMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                           requestMsg.RequestId,
                                           "N/A",
                                           String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                                         requestMsg.RawMessage.Id,
                                                         QueueAccessor.ImageRequestQueue,
                                                         QueueAccessor.ImageRequestQueue.PoisonThreshold),
                                           "N/A",
                                           Environment.NewLine);
                    }
                }
                #endregion

                #region COMPLETED SLICE NOTIFICATION
                var responseMsg = QueueAccessor.IsAvailable ? QueueAccessor.SliceResponseQueue.AcceptMessage <SliceResponseMessage>() : null;
                if (responseMsg != null)
                {
                    // check for possible poison message
                    if (responseMsg.RawMessage.DequeueCount <= responseMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor  = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(responseMsg.SliceUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(responseMsg.ClientId));

                            // get the job data (from Azure table) indicating number of slices and the tile size
                            var job = tableAccessor.GetJobByRequestId(responseMsg.RequestId);
                            if ((job != null) && (job.Slices > 0) && (job.TileSize > 0) && (job.SourceWidth > 0) && (job.SourceHeight > 0))
                            {
                                // get slices processed so far
                                var processedSliceUris = blobAccessor.RetrieveImageUris(BlobAccessor.SliceOutputContainer, responseMsg.BlobName).ToList();

                                // if we have the expected number, this is the last slice to complete
                                if (processedSliceUris.Count() == (Int32)job.Slices)
                                {
                                    Byte[] finalImgBytes = ImageUtilities.StitchAndMend(
                                        processedSliceUris, blobAccessor.RetrieveImages,
                                        (byte)job.TileSize, new Size(job.SourceWidth, job.SourceHeight));

                                    Uri finalImageUri = blobAccessor.StoreImage(finalImgBytes, BlobAccessor.ImageOutputContainer, responseMsg.BlobName);

                                    QueueAccessor.ImageResponseQueue.SubmitMessage <ImageResponseMessage>
                                        (responseMsg.ClientId, responseMsg.RequestId, finalImageUri);
                                }
                            }
                            else
                            {
                                throw new SystemException("Metadata for job {0} in Jobs table was not found or is invalid");
                            }

                            // message processed successfully
                            responseMsg.DeleteFromQueue();
                        }
                        catch (Exception e)
                        {
                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                             responseMsg.RequestId,
                                             e.GetType(),
                                             e.Message,
                                             e.StackTrace,
                                             Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison message from the queue
                        responseMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                           responseMsg.RequestId,
                                           "N/A",
                                           String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                                         responseMsg.RawMessage.Id,
                                                         QueueAccessor.SliceResponseQueue,
                                                         QueueAccessor.SliceResponseQueue.PoisonThreshold),
                                           "N/A",
                                           Environment.NewLine);
                    }
                }
                #endregion

                #region MOST SINCERELY DONE NOTIFICATION
                var completeMsg = QueueAccessor.IsAvailable ? QueueAccessor.ImageResponseQueue.AcceptMessage <ImageResponseMessage>() : null;
                if (completeMsg != null)
                {
                    // check for possible poison message
                    if (completeMsg.RawMessage.DequeueCount <= completeMsg.Queue.PoisonThreshold)
                    {
                        try
                        {
                            // instantiate storage accessors
                            blobAccessor  = new BlobAccessor(StorageBroker.GetStorageConnectionStringForAccount(completeMsg.ImageUri));
                            tableAccessor = new TableAccessor(StorageBroker.GetStorageConnectionStringForClient(completeMsg.ClientId));

                            // get the completed job entity from table storage
                            var job = tableAccessor.GetJobByRequestId(completeMsg.RequestId);
                            if (job != null)
                            {
                                // update pointer to completed image (and the finish time)
                                job.FinalImageUri = completeMsg.ImageUri.ToString();
                                job.FinishTime    = DateTime.UtcNow;

                                tableAccessor.UpdateJob(job);

                                tableAccessor.WriteStatusEntry(completeMsg.RequestId, "Request complete.");
                            }
                            else
                            {
                                Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                                   completeMsg.RequestId,
                                                   "N/A",
                                                   "Request completed, but record not found in Jobs table",
                                                   "N/A",
                                                   Environment.NewLine);
                            }

                            // only notify user (or try to) once!
                            if (completeMsg.RawMessage.DequeueCount == 1)
                            {
                                try
                                {
                                    // notify via service bus that request is complete
                                    if (job != null)
                                    {
                                        Notifier.SendRequestCompletedNotification(
                                            job.ClientId,
                                            completeMsg.RequestId,
                                            completeMsg.ImageUri);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                                       completeMsg.RequestId,
                                                       e.GetType(),
                                                       e.Message,
                                                       e.StackTrace,
                                                       Environment.NewLine);
                                }
                            }

                            // message processed successfully
                            completeMsg.DeleteFromQueue();
                        }

                        catch (Exception e)
                        {
                            // something really bad happened!
                            Trace.TraceError("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                             completeMsg.RequestId,
                                             e.GetType(),
                                             e.Message,
                                             e.StackTrace,
                                             Environment.NewLine);
                        }
                    }
                    else
                    {
                        // remove poison m essage from the queue
                        completeMsg.DeleteFromQueue();
                        Trace.TraceWarning("Request: {0}{4}Exception: {1}{4}Message: {2}{4}Trace: {3}",
                                           completeMsg.RequestId,
                                           "N/A",
                                           String.Format("Possible poison message [id: {0}] removed from queue '{1}' after {2} attempts",
                                                         completeMsg.RawMessage.Id,
                                                         QueueAccessor.ImageResponseQueue,
                                                         QueueAccessor.ImageResponseQueue.PoisonThreshold),
                                           "N/A",
                                           Environment.NewLine);
                    }
                }
                #endregion

                // only sleep if we didn't do anything this time through
                if ((requestMsg == null) && (responseMsg == null) && (completeMsg == null))
                {
                    Thread.Sleep(10000);
                }
            }
        }