Click on Part 1 and Part 2 of this series to review the previous examples and code. First and foremost have the existing code base created in the other two examples opened and ready in Visual Studio 2010. Next, I’ll just start rolling ASAP.
In the JunkTrunk.Storage Project add the following class file and code to the project. This will get us going for anything else we needed to do for the application from the queue perspective.
[sourcecode language=”csharp”]
public class Queue : JunkTrunkBase
{
public static void Add(CloudQueueMessage msg)
{
Queue.AddMessage(msg);
}
public static CloudQueueMessage GetNextMessage()
{
return Queue.PeekMessage() != null ? Queue.GetMessage() : null;
}
public static List<CloudQueueMessage> GetAllMessages()
{
var count = Queue.RetrieveApproximateMessageCount();
return Queue.GetMessages(count).ToList();
}
public static void DeleteMessage(CloudQueueMessage msg)
{
Queue.DeleteMessage(msg);
}
}
[/sourcecode]
Once that is done open up the FileBlobManager.cs file in the Models directory of the JunkTrunk ASP.NET MVC Web Application. In the PutFile() Method add this line of code toward the very end of that method. The method, with the added line of code should look like this.
[sourcecode language=”csharp”]
public void PutFile(BlobModel blobModel)
{
var blobFileName = string.Format("{0}-{1}", DateTime.Now.ToString("yyyyMMdd"), blobModel.ResourceLocation);
var blobUri = Blob.PutBlob(blobModel.BlobFile, blobFileName);
Table.Add(
new BlobMeta
{
Date = DateTime.Now,
ResourceUri = blobUri,
RowKey = Guid.NewGuid().ToString()
});
Queue.Add(new CloudQueueMessage(blobUri + "$" + blobFileName));
}
[/sourcecode]
Now that we have something adding to the queue, we want to process this queue message. Open up the JunkTrunk.WorkerRole and make sure you have the following references in the project.
Next create a new class file called PhotoProcessing.cs. First add a method to the class titled ThumbnailCallback with the following code.
[sourcecode language=”csharp”]
public static bool ThumbnailCallback()
{
return false;
}
[/sourcecode]
Next add another method with a blobUri string and filename string as parameters. Then add the following code block to it.
[sourcecode language=”csharp”]
private static void AddThumbnail(string blobUri, string fileName)
{
try
{
var stream = Repository.Blob.GetBlob(blobUri);
if (blobUri.EndsWith(".jpg"))
{
var image = Image.FromStream(stream);
var myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
var thumbnailImage = image.GetThumbnailImage(42, 32, myCallback, IntPtr.Zero);
thumbnailImage.Save(stream, ImageFormat.Jpeg);
Repository.Blob.PutBlob(stream, "thumbnail-" + fileName);
}
else
{
Repository.Blob.PutBlob(stream, fileName);
}
}
catch (Exception ex)
{
Trace.WriteLine("Error", ex.ToString());
}
}
[/sourcecode]
Last method to add to the class is the Run() method.
[sourcecode language=”csharp”]
public static void Run()
{
var queueMessage = Repository.Queue.GetNextMessage();
while (queueMessage != null)
{
var message = queueMessage.AsString.Split(‘$’);
if (message.Length == 2)
{
AddThumbnail(message[0], message[1]);
}
Repository.Queue.DeleteMessage(queueMessage);
queueMessage = Repository.Queue.GetNextMessage();
}
}
[/sourcecode]
Now open up the WorkerRole.cs File and add the following code to the existing methods and add the additional even method below.
[sourcecode language=”csharp”]
public override void Run()
{
Trace.WriteLine("Junk Trunk Worker entry point called", "Information");
while (true)
{
PhotoProcessing.Run();
Thread.Sleep(60000);
Trace.WriteLine("Working", "Junk Trunk Worker Role is active and running.");
}
}
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString");
RoleEnvironment.Changing += RoleEnvironmentChanging;
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
RoleEnvironment.RequestRecycle();
}
}
};
});
Storage.JunkTrunkSetup.CreateContainersQueuesTables();
return base.OnStart();
}
private static void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
if (!e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)) return;
Trace.WriteLine("Working", "Environment Change: " + e.Changes.ToList());
e.Cancel = true;
}
[/sourcecode]
At this point everything needed to kick off photo processing using Windows Azure Storage Queue as the tracking mechanism is ready. I’ll be following up these blog entries with some additional entries regarding rafactoring and streamlining what we have going on. I might even go all out and add some more functionality or some such craziness! So hope that was helpful and keep reading. I’ll have more bits of rambling and other trouble coming down the blob pipeline soon! Cheers!
hey!!where is the “RepositoryBase” class in this project?
are you missing the assembly reference??
please respond me as soon as possible.
thanks & regards
Debasish Mishra
My mistake, I’ll change it as soon as I can, but look back at Part 1 of the series at the JunkTrunkBase. This is what you’re looking for. Let me know if you have any other issues.
yup everything is fine now only errors are showing in “BlobMetaContext” class near Data in “Add” function ,i.e “Could not find an implementation of the query pattern for source type ‘System.Linq.IQueryable’. ‘Where’ not found. Consider explicitly specifying the type of the range variable ‘e’.”
same error was also shown in “Table” class near “Context.Data”
Thanks & Regards
please reply adron,i am waiting 4 ur reply..
You didn’t actually ask another question. As for that error, it isn’t reproducible so you will have to reproduce and troubleshoot yourself. Good luck.