I’ve been wanting to get a write up done for WordPress on AWS, the fact that it is free for a year, since they’ve released the free-tier many months ago. Well I finally got around to it, however it isn’t a write up. I went ahead and put the work in to produce a video of the steps for setup & configuration. Enjoy.
The commands to install php, mysql, httpd (apache), and manipulate the config files are included below for copy and paste needs.
Create a Linux Instance on AWS – create & assign an IP Address
————————————————————————————
# Web application to manage MySQL
# Order Deny,Allow
# Deny from all
Allow from all
Alias /phpmyadmin /usr/share/phpmyadmin
Alias /phpMyAdmin /usr/share/phpmyadmin
Alias /mysqladmin /usr/share/phpmyadmin
————————————————————————————
service httpd restart
service mysqld start
/usr/bin/mysqladmin -u root password ‘somepassword’
vi /etc/httpd/conf.d/phpmyadmin.conf
vi /usr/share/phpmyadmin/config.inc.php
Here’s the class that has a Func setup as a property. The reason this is setup, is so that the stream can actually be stubbed on the ComplianceReportingJob. Otherwise if the Stream was just being used as is, instantiated in the class, or passed in via injection, we still couldn’t get it mocked or stubbed. Especially if the class ComplianceReportingJob is under test.
[sourcecode language=”csharp”]
public class ComplianceReportingJob : IJob
{
readonly ITradeRepository tradeRepo;
readonly IFileSystem fileSys;
public ComplianceReportingJob(ITradeRepository tradeRepository, IFileSystem fileSystem)
{
tradeRepo = tradeRepository;
StreamedFile = filename => new FileStream(filename, FileMode.Create);
}
public Func<string, Stream> StreamedFile { get; set; }
}
[/sourcecode]
What we have here is the context being setup, with the property being stubbed with a fake StreamedFile = filename => new MemoryStream(). So if you’re looking for a way to test streams with .NET, this is a way around the limitations of the framework.
[sourcecode language=”csharp”]
public class with_a_compliance_report_job
{
protected static ITradeRepository tradeRepository;
protected static IFileSystem fileSys;
protected static ComplianceReportingJob job;
This is a pretty sweet solution, for now. The ideal solution however, would be that Microsoft fixes the framework, which is very unlikely to happen. The whole closed, sealed, and otherwise locked up framework stack is a massive problem with testability. Which then directly impacts maintainability and other things over time.
I did some searches for tutorials on Entity Framework (EF) + Code First. Most of the tutorials I found involved clicking on some design time view and right clicking to add columns, then clicking and right clicking to generate the code first SQL. It was neat, it was clean, and it was sort of fast. However, it didn’t beat FluentNHibernate in cleanliness. There still ended up being some huge and nasty generated (from the design time) file and some other things that just didn’t sit well with me. With the host of other things that are just now getting developed for EF that have been in NHibernate for ages I’ve decided to yank Entity Framework support for now and just stick to NHibernate + FluentNHibernate. Simply, it just works better and I have more immediate support, feedback, and input into what is available with NHibernate. For Entity Framework nobody really has any of that, one has to wait for the Microsoft machine to move forward on design decisions before something gets dropped either via a proper version or CTP. I’ll stick to the more responsive open source solution, k thx. 🙂
HOWEVER, In the future I do intend to add Entity Framework support, I’m just not spending the time right now. I’d be perfectly happy if someone else wants to do so, just let me know…
In other news from the UI from of the Infrastructure Project, I’ve made another decision to use the Zen Garden CSS to setup the original layouts & such. Since it is the UI, I thought that going with something that designers are more familiar with instead of the ASP.NET MVC Themes oddities (which I don’t even really know where they’re hiding those these days) would make things even simpler from that aspect. A clear separation of concerns for devs vs. graphic artists & layout pros.
Anyway, that’s all committed and I’ll be building a new template before the end of this week. As always, if you’re interested in adding to the project, or just using it, I’d love any and all feedback.
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 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()
});
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. Windows Azure References
Next create a new class file called PhotoProcessing.cs. First add a method to the class titled ThumbnailCallback with the following code.
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!
If you haven’t read Part 1 of this series (part 3 click here), you’ll need to in order to follow along with the JunkTrunk Repository. Open the solution up if you haven’t already and navigate to the Models Folder within the ASP.NET MVC JunkTrunk Project. In the folder add another class titled FileItemModel.cs and BlobModel.cs. Add the following properties to the FileItemModel.
[sourcecode language=”csharp”]
public class FileItemModel
{
public Guid ResourceId { get; set; }
public string ResourceLocation { get; set; }
public DateTime UploadedOn { get; set; }
}
[/sourcecode]
Add the following property to the BlobModel and inherit from the FileItemModel Class.
[sourcecode language=”csharp”]
public class BlobModel : FileItemModel
{
public Stream BlobFile { get; set; }
}
[/sourcecode]
Next add a new class file titled FileBlobManager.cs and add the following code to the class.
[sourcecode language=”csharp”]
public class FileBlobManager
{
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()
});
}
public BlobModel GetFile(Guid key)
{
var blobMetaData = Table.GetMetaData(key);
var blobFileModel =
new BlobModel
{
UploadedOn = blobMetaData.Date,
BlobFile = Blob.GetBlob(blobMetaData.ResourceUri),
ResourceLocation = blobMetaData.ResourceUri
};
return blobFileModel;
}
public List GetBlobFileList()
{
var blobList = Table.GetAll();
public void Delete(string identifier)
{
Table.DeleteMetaDataAndBlob(Guid.Parse(identifier));
}
}
[/sourcecode]
Now that the repository, management, and models are all complete the focus can turn to the controller and the views of the application. At this point the break down of each data element within the data transfer object and the movement of the data back and forth becomes very important to the overall architecture. One of the things to remember is that the application should not pass back and forth data such as URIs or other long easy to hack strings. This is a good place to include Guids or if necessary integer values that identify the data that is getting created, updated, or deleted. This helps to simplify the UI and help decrease the chance of various injection attacks. The next step is to open up the HomeController and add code to complete each of the functional steps for the site.
[sourcecode language=”csharp”]
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to the Windows Azure Blob Storing ASP.NET MVC Web Application!";
var fileBlobManager = new FileBlobManager();
var fileItemModels = fileBlobManager.GetBlobFileList();
return View(fileItemModels);
}
public ActionResult About()
{
return View();
}
public ActionResult Upload()
{
return View();
}
public ActionResult UploadFile()
{
foreach (string inputTagName in Request.Files)
{
var file = Request.Files[inputTagName];
if (file.ContentLength > 0)
{
var blobFileModel =
new BlobModel
{
BlobFile = file.InputStream,
UploadedOn = DateTime.Now,
ResourceLocation = Path.GetFileName(file.FileName)
};
var fileBlobManager = new FileBlobManager();
fileBlobManager.PutFile(blobFileModel);
}
}
return RedirectToAction("Index", "Home");
}
public ActionResult Delete(string identifier)
{
var fileBlobManager = new FileBlobManager();
fileBlobManager.Delete(identifier);
return RedirectToAction("Index", "Home");
}
}
[/sourcecode]
The view hasn’t been created for the Upload just yet, so the method will cause a build error at this point. But before I add a view for this action, I’ll cover what has been created for the controller.
The Index Action I’ve changed moderately to have a list of the Blobs that are stored in the Windows Azure Blob Storage. This will be pulled from the manager class that we created earlier and passed into the view for rendering. I also, just for cosmetic reasons, changed the default display message passed into the ViewData so that the application would have something displayed more relevant to the application.
The About message I just left as is. The Upload action simply returns what will be a view we create.
The UploadFile Action checks for files within the request, builds up the model and then puts the model into storage via the manager.
The last method is the Delete Action that instantiates the manager and then calls a delete against the storage. This action then in turn traces back through, finds the Table & Blob Entities that are related to the specific blob and deletes both from the respective Windows Azure Storage Table and Blob Mediums.
The next step is to get the various views updated or added to enable the upload and deletion of the blob items.
Add a view titled Upload.aspx to the Home Folder of the Views within the JunkTrunk Project.
Upload View
First change the inherits value for the view from System.Web.Mvc.ViewPage to System.Web.Mvc.ViewPage. After that add the following HTML to the view.
<div class="editor-label">
Select file to upload to Windows Azure Blob Storage:
</div>
<div class="editor-field">
<input type="file" id="fileUpload" name="fileUpload" />
</div>
<p>
<input type="submit" value="Upload" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
[/sourcecode]
After adding the HTML, then change the HTML in the Index.aspx View to have an action link for navigating to the upload page and for viewing the list of uploaded Blobs. Change the inherits first form System.Web.Mvc.ViewPage to System.Web.Mvc.ViewPage<IEnumerable>. The rest of the changes are listed below.
Make sure the Windows Azure Project is set as the startup project and click on F5 to run the application. The following page should display first.
The Home Page o' Junk Trunk
Click through on it to go to the upload page.
Selecting an Image to Put in The Junk Trunk
On the upload page select and image to upload and then click on upload. This will then upload the image and redirect appropriately to the home page.
The Image in the Junk Trunk
On the home page the list should now have the uploaded blob image listed. Click delete to delete the image. When deleted the table and the blob itself will be removed from the Windows Azure Storage. To see that the data & image are being uploaded open up the Server Explorer within Visual Studio 2010.
Visual Studio 2010 Server Explorer
View the data by opening up the Windows Azure Storage tree. Double click on either of the storage mediums to view table or blob data.
You must be logged in to post a comment.