Scaling cloud apps with the .NET Framework 4.5 - Really great post, that introduce some new features of the .Net framework 4.5 (now available in Azure web site) and how to use them in a scaling perspective using async.
Windows Server 2012 Now Available on AWS - A new series called Windows Wednesdays just kicked off with this nice post about the new availability of Windows Server 2012 on AWS.
AppFabric - Frequently Asked Development Questions (Ed Price - MSFT Ed Price - MSFT Microsoft MSFT 122,146 Points 25 20 17 Recent Achievements Proposed Answerer III Gallery Contributor II Wiki Ninja View Profile) - Good questions... with their answers.
Programming
Changes in ADFS 2.1 from ADFS 2.0 - Important things to know when migrating in addition to remember where you saved the artifacts creation scripts.
All Things Distributed (Werner Vogels) - Big announcement from AWS for the .Net community. Amazon is releasing is RDS for MSSQL and a tools kit for Visual Studio.
Ajax Control Toolkit May 2012 Release - Great! The timing is perfect. One day after this new release some project arrived and they need exactly this new version of the upload control... thanks!
Create a Continuous Client Using Portable Class Libraries - Very nice article. By following the realisation of an application to solve a real world problem, the author introduces the client portable library “cpl” that gives the opportunity to easily write a cross platform application.
“there is, as Joshua Topolsky puts it, “a missing link in our computing experience” (engt.co/9GVeKl). “
The key to AddOrUpdate (Arthur Vickers) - While waiting for the next release of EF this post explain very clearly how to implement an extension method to help use in a more generic context when we want the same functionality of the DbSet.Find in a AddUpdateEntity method.
Michael Stephenson - Tips on when not using BizTalk config file and reference on another post to more details.
"I wrote a blog post a few years ago around the options for where you could put configuration settings in BizTalk (Click here)."
Miscellaneous
The Blog of Scott Hanselman - Interesting post here Scott explain how he did introduce Star Wars to is kids. I like the 20 minutes segment idea.
The Myth of Informed Consent - I agree, how many times did you got a firewall or anti-virus popup asking to approve something that you really don't know about? That why we install them, so they should take the decision...
The key to AddOrUpdate (Arthur Vickers) - While waiting for the next release of EF this post explain very clearly how to implement
“You Complete Me” Says SharePoint to Windows Azure (Jonathan Rozenblit) - Really nice post that just open the possibilities on how could be implanted Azure with other application and in this case with SharePoint.
Why Infrastructure As A Service Is A Bad Deal - It could be difficult to have a idea of the saving you could do going in the cloud. This post only looks the storage scenario. You could be surprise of the result, but I bet that the arrival of Google Drive and is aggressive pricing will makes thing moved.
Windows Azure Diagnostics–From the Ground Up (Greg Oliver) - Really nice post with a lot of good references and a lot of information. Perfect to get started or have a better understanding of Azure diagnostics.
Fun with the Service Bus (Part 1) - What a great tutorial! This post is covering a lot a material by doing for a to z an application where the heart is Azure Service Bus.
Code First model builder versions (Arthur Vickers) - This post explain how to configure EF code first to avoid any breaking code when updating the framework to a newer version. Nice work.
Créer son propre Gem et le publier - Very nice tutorial (in French) that explain in detail with a simple case how to create and also publish a Ruby Gem.
Hit the Presentation Sweet Spot - Twenty minutes is very short. Maybe it is a good idea for a specific type of presentation... How do you plan a 2-3 formation?
Your Personal Brand as a Developer: Implementing (Part 2 of 2) (Jonathan Rozenblit) - Part 2 on an unusual topic but important. Our brand, as a person. On the internet everything is amplified and could be seen by a lot of people very quickly. A post to read "before it is too late".
Coping with Email Overload (Peter) - This could be a good advice for a lot of people. While I'm working on a project where co-workers are across the country I not sure I can do this but maybe tweaking it with rules for only those people.
Microsoft Private Cloud Part 1 - Nice first post of a series comparing Azure with private cloud. This one is more about being prepare to the real comparison and define what is private cloud.
Windows Azure Storage and Concurrent Access (Larry Franks) - Known a to read/write in Azure Storage is not enough when doing multi-instance. Learn how-to manage this situation in this post.
Exploring Cloud Architecture - Nice article that present different cloud architecture to follow your cost/efficiency strategies.
BizTalk in the Cloud, One Step Closer Part 1 (Jean-Paul Smit) - Great post (first part of series of two) that present the new interface of schemas and mapping in the new CTP release of Azure Service bus EAI and compare them to the BizTalk ones.
BizTalk in the Cloud, One Step Closer Part 2 (Jean-Paul Smit) - A really great post that continue to pass all the functionalities of the new (still in CTP) Azure Service Bus EAI and making the correlation with the BizTalk equivalence.
Programming
Mercurial vs Git: Why Mercurial? - Great posts series about source control. Because source control is so important, knowing why to pick git or mercurial is really important.
WebAPI and Ninject (Shawn Wildermuth) - Nice trick with Ninject...as the author said easy when you know how to.
an opportunity to get application security right - Nice post discussing about in the beginning of the Internet where enterprises didn't taken seriously the security menace. Today with a lot of people going to the cloud we shouldn't make the same mistake.
Amazon Web Services Blog - Amazon announce a new free product/feature the cloudWatch Metrics that will help to visualize how your part of the cloud is use.
SSIS package needs an outbound access to port 1433
The “NoSQL” Gene in SQL Azure Federations (Cihan Biyikoglu) - Great post. A bit old, but it explain a lot of key concept about the NoSql of the new Azure Federation.
Microsoft has provided the storage credentials for the local Storage Emulator on MSDN. Here’s a quick place to copy the default name and key: AccountName AccountKey
AzureWatch vs. Azure Fabric Controller. (Kurt Claeys) - By answering a question about the difference between AzureWatch (a product from Paraleap) and Azure Fabric this post introduce a really good tool to monitor and help to scaleup your system.
Announcing SQL Azure Data Sync Preview Refresh (Gregory Leake) - Good news. This will became a great tool. It's already a good one simple and efficient. Don't forget to update your sync agent.
Managing cloud computing security requires planning - This post explain which question you should ask yourself about when planning your move to the cloud... or when you already there. Better later then never.
Getting Started with Windows Azure – part2 (ScottGu) - In this second post of a series Scott Gu is taking our hand to show how to get started for free and why we shouldn't worry about getting charge because of this new feature:the billing limit.
“[…] Spending limits are a new feature we added to Windows Azure last month, and ensure that you never have to worry about accidentally going over the resources included in a free offer and being charged […]”
“[…]You can learn more about the spending limit feature here[…]”
the Module pattern (part 4) – debugging - In this fourth post of the series is using a intrusive but really efficient method to debug the clock watch module.
Using HTML5 Canvas for Data Visualization - This post present the HTML5 canvas by building a chart. It look a lot of work compare of using chart component, put we can do everything...
Cloud is complex—deal with it (James Urquhart) - It’s up to people to make technologies that survive cloud as a complex system—one component at a time. That’s, well, how you deal with it.
The biggest missing link here, is the extensibility with custom components. At this moment, it doesn’t look possible to have (de)batching, custom validation, zipping and all these other things we do in BizTalk pipeline components.
Windows Azure Caching Strategies - Great article that demystify where we should cache our data by adding a layer of indirection.
A good post about using the Windows Azure CDN can be found on Steve Marx’s blog.
There are a couple of variations on that theme available, and I discussed one in a blog post from March 2010.
The Elements of Distributed Architecture (Clemens Vasters) – I just watch few minutes, but it look great! Introduction to the key elements of distributed software architecture. [video]
Four Questions With … Clemens Vasters (seroter)- Interesting topics in this interview with one of the public face of Azure team about different topic.
MVC on Azure for Beginner (Henry He) - Definitively a good starting point for everyone want to start or try Azure and Asp.Net MVC.
Introducing Microsoft Sync Framework - A good product that is the core of the new Azure Data Sync. If you want a better configuration capability you will need sync framework.
How to avoid chaos in the cloud - We are at a time were the cloud is only beginning and nobody know how it will grow... this post ask so questions about the near future
New SQL Azure lab available (How to move data to SQL Azure) (Susan Ibach) - Microsoft Codename “Data Transfer” Tutorial (Liam Cavanagh - MSFT)- Nice tools quick and simple. However I got some hard time trying it, my Excel or csv file was not process. Finally I discover that the problem was my column name. Don't use ID as name for a column. Use something less generic like CustomerID... and it will work just fine.
I was re-doing some of the labs in the Windows Azure Platform Training Kit (WAPTK) when one of then didn't works: MessagingWithQueue. A got this error message:
Could not connect to net.tcp://xxxx.servicebus.windows.net:9354/.
The connection attempt lasted for a time span of 00:00:00.0615234.
TCP error code 10061: No connection could be made because the target machine actively refused it.
Quickly this message is saying that the port 9354 need to be open. So I was going to ask to open this port, but then I ask my self: “What if I couldn't?” Does Azure service Bus suppose to be super flexible and give me the opportunity to you all kind of connection? Of course it does, so I decide to make a RESTful version of this lab.
Let’s begin
Create a new Cloud project in Visual Studio, and add a web role. In fact, regular web project will work just fine, but to keep it close to the original lab I will start with a cloud on. In the content folder add preloader.gif and override the Site.css (all the code, images and files are available here). In the View / Shared folder override the Site.Master and in View / Home override Index.aspx. You can run now the application, you should see something like that:
Create Azure AppFabric Service Bus
On the Azure management portal at windows.azure.com In the Service Bus section, create a new Service Bus. You will need the Service Gateway, the Default Issuer (always “owner” in the CTP) and the Default Key.
Create New Queues
To Create a queue the button “Create” in section B will send the text, the queue name, to the Home controller and let us know the result. To do that let’s add some JavaScript /JQuery code in the Index page.
var getQueuesUrl = '< %= Url.Action("Queues") % >';
$(document).ready(function () {
loadQueues();
$("#createQueue").submit(function (event) {
event.preventDefault();
var url = $(this).attr('action');
var queueName = $("#queueName").val();
$(".loading").show();
$("#send").attr("disabled", "true");
$("#retrieve").attr("disabled", "true");
$.post(url, { queueName: queueName })
.success(function (response) { renderCreateQueueStatus(response); })
.error(function () { renderCreateQueueStatus(false); });
});
});
function renderCreateQueueStatus(response) {
if (response) {
$("#createQueueStatus").html("Queue created successfully!");
loadQueues();
} else {
$("#createQueueStatus").html("An error occurred, please try again later.");
}
$(".loading").hide();
$("#send").attr("disabled", "");
$("#retrieve").attr("disabled", "");
}
function loadQueues() {
$.get(getQueuesUrl).success(function (response) {
var ul = $("fieldset.center > ul");
var sendMsgCombo = $("#sendMessageQueue");
var receiveMsgCombo = $("#retrieveMessageQueue");
sendMsgCombo.children().remove();
receiveMsgCombo.children().remove();
ul.children().remove();
for (var i = 0; i < response.length; i++) {
var item = response[i];
sendMsgCombo.append('<option value="' + item.Name + '">' + item.Name + '</option>');
receiveMsgCombo.append('<option value="' + item.Name + '">' + item.Name + '</option>');
ul.append('<li><label>' + item.Name + '</label><div class="msgCountOf' + item.Name.replace(/ /g, '') + '" style="float:right"><label>Messages</label></div></li>');
updateMessageCountOf(item.Name, item.Messages);
}
});
$(".loading").hide();
}
function updateMessageCountOf(queueName, numberOfMessages) {
var message = numberOfMessages + " Messages";
if (numberOfMessages == "0") message = "No Messages";
if (numberOfMessages == "1") message = numberOfMessages + " Message";
$("div.msgCountOf" + queueName.replace(/ /g, '') + " > label").html(message);
}
Once the document is ready loadQueues() is called. This function will loop through a list of queues name and fill the two listbox and the build the middle list .
Using Jquery the $("#createQueue") add a submit function to the button with the ID createQueue and on the success or error will call the function renderCreateQueueStatus to update the content of the Label createQueueStatus. Then recall loadQueues() so it can refresh the queues lists.
On the server side now we will need a function CreateQueue that accept a string parameter as queue name and return a JsonResult. This function should act as a HttpPost. To communicate a token is needed. This is done by the primary call to Index. It’s creating a token for us with the issuer name and issuer secret of our Service bus with the function GetToken.
Put the information about your Service Bus (Service Gateway, Issuer and Key) in the Settings.The default constructor load this information.
To update the list of our queues we will use a function Queues(). This will download the information from “$Resources/Queues” and build a array of Json object with properties: Name and Messages. It took me some time before this Linq query works, the tricks is to use the namespace when looking for a node.
public class HomeController : Controller
{
private String mServiceNamespace;
private static String mBaseAddress;
private static String mToken;
private String mIssuerName;
private String mIssuerSecret;
private const String SBHOSTNAME = "servicebus.windows.net";
private const String ACSHOSTNAME = "accesscontrol.windows.net";
private const String ATOMNS = "{http://www.w3.org/2005/Atom}";
private const String SBNS = "{http://schemas.microsoft.com/netservices/2010/10/servicebus/connect}";
public HomeController()
{
mServiceNamespace = RoleEnvironment.GetConfigurationSettingValue("namespaceAddress");
mIssuerName = RoleEnvironment.GetConfigurationSettingValue("issuerName");
mIssuerSecret = RoleEnvironment.GetConfigurationSettingValue("issuerSecret");
mBaseAddress = "https://" + mServiceNamespace + "." + SBHOSTNAME + "/";
}
public ActionResult Index()
{
try
{
// Get a SWT token from the Access Control Service, given the issuerName and issuerSecret values.
mToken = GetToken(mIssuerName, mIssuerSecret);
}
catch (WebException we)
{
using (HttpWebResponse response = we.Response as HttpWebResponse)
{
if (response != null)
{
ViewBag.Message += Environment.NewLine + (new StreamReader(response.GetResponseStream()).ReadToEnd());
}
else
{
ViewBag.Message += Environment.NewLine + (we.ToString());
}
}
}
return View();
}
[HttpPost]
public JsonResult CreateQueue(String queueName)
{
try
{
var _queueAddress = mBaseAddress + queueName;
var _webClient = GetWebClient();
var _putData = @"<entry xmlns=""http://www.w3.org/2005/Atom"">
<title type=""text"">" + queueName + @"</title>
<content type=""application/xml"">
<QueueDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"" />
</content>
</entry>";
byte[] _response = _webClient.UploadData(_queueAddress, "PUT", Encoding.UTF8.GetBytes(_putData));
var _queueDescription = Encoding.UTF8.GetString(_response);
return Json(_queueDescription, JsonRequestBehavior.AllowGet);
}
catch
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult Queues()
{
var _xDoc = XDocument.Parse(GetResources("$Resources/Queues"));
var _queues = (from entry in _xDoc.Descendants(ATOMNS + "entry")
select new
{
Name = entry.Element(ATOMNS + "title").Value,
Messages = entry.Element(ATOMNS + "content").Element(SBNS + "QueueDescription").Element(SBNS + "MessageCount").Value
}).ToArray();
return Json(_queues, JsonRequestBehavior.AllowGet);
}
private WebClient GetWebClient()
{
var _webClient = new WebClient();
_webClient.Headers[HttpRequestHeader.Authorization] = mToken;
return _webClient;
}
private String GetToken(String issuerName, String issuerSecret)
{
var acsEndpoint = "https://" + mServiceNamespace + "-sb." + ACSHOSTNAME + "/WRAPv0.9/";
var realm = "http://" + mServiceNamespace + "." + SBHOSTNAME + "/";
var _values = new NameValueCollection();
_values.Add("wrap_name", issuerName);
_values.Add("wrap_password", issuerSecret);
_values.Add("wrap_scope", realm);
var _webClient = new WebClient();
byte[] response = _webClient.UploadValues(acsEndpoint, _values);
var _responseString = Encoding.UTF8.GetString(response);
var _responseProperties = _responseString.Split('&');
var _tokenProperty = _responseProperties[0].Split('=');
var _token = Uri.UnescapeDataString(_tokenProperty[1]);
return "WRAP access_token=\"" + _token + "\"";
}
private String GetResources(String resourceAddress)
{
String _fullAddress = mBaseAddress + resourceAddress;
var _webClient = GetWebClient();
return _webClient.DownloadString(_fullAddress); ;
}
}
Send a Message
On the client side using JQuery we add a submit event that will call SendMessage from our controller then update the status and the message count.
$(document).ready(function () {
$("#sendMessage").submit(function (event) {
event.preventDefault();
var url = $(this).attr('action');
var queueName = $("#sendMessageQueue option:selected").val();
var message = $("#messageToSend").val();
$(".loading").show();
$("#create").attr("disabled", "true");
$("#retrieve").attr("disabled", "true");
$.post(url, { message: message, queueName: queueName })
.success(function (response) {
renderSendMessageStatus(response);
updateMessageCountOf(queueName, response);
})
.error(function () { renderSendMessageStatus(false); });
});
});
function updateMessageCountOf(queueName, numberOfMessages) {
var message = numberOfMessages + " Messages";
if (numberOfMessages == "0") message = "No Messages";
if (numberOfMessages == "1") message = numberOfMessages + " Message";
$("div.msgCountOf" + queueName.replace(/ /g, '') + " > label").html(message);
}
function renderSendMessageStatus(response) {
if (response) $("#sendMessageStatus").html("Message sent successfully!");
else $("#sendMessageStatus").html("An error occurred, please try again later.");
$(".loading").hide();
$("#create").attr("disabled", "");
$("#retrieve").attr("disabled", "");
}
function updateMessageCountOf(queueName, numberOfMessages) {
var message = numberOfMessages + " Messages";
if (numberOfMessages == "0") message = "No Messages";
if (numberOfMessages == "1") message = numberOfMessages + " Message";
$("div.msgCountOf" + queueName.replace(/ /g, '') + " > label").html(message);
}
On the server side the SendMessage function will post our message.
[HttpPost]
public JsonResult SendMessage(String queueName, String message)
{
var _fullAddress = mBaseAddress + queueName + "/messages" + "?timeout=60";
var _webClient = GetWebClient();
_webClient.UploadData(_fullAddress, "POST", Encoding.UTF8.GetBytes(message));
return Json("1", JsonRequestBehavior.AllowGet);
}
Retrieve a Message
Finally to retrieve a message wee need to select a queue then send it to the server side. I modify this part of the code because I’m not using the brokeredMessage so I don't have all the properties from the original code lab.