VB Magic

2014/03/31

Connecting an Azure Web Role to an existing Virtual Network connected to company WAN

Filed under: Azure — Tags: , , , , , , — vbmagic @ 3:34 pm

I’ve just been trying to deploy an Azure web role so that it would be available on our company WAN. This is easy for a VM as you just need to specify the Virtual Network when you create the VM. But for a Cloud Service it’s not so straight forward. It turned out to be pretty simple though once I had done some research. The first thing that needs to happen is a small change to the ServiceConfiguration.Cloud.csfg file.

...
  </Role>
  <NetworkConfiguration>
    <VirtualNetworkSite name="myVirtualNetwork" />
    <AddressAssignments>
      <InstanceAddress roleName="myWebSite">
        <Subnets>
          <Subnet name="MySubNet" />
        </Subnets>
      </InstanceAddress>
    </AddressAssignments>
  </NetworkConfiguration>
...

The VirtualNetworkSite name is the name of your Virtual Network.
InstanceAddress roleName is the name of the Web Role in your Cloud Service (Usually the name of your website in your solution).
Subnet name can be found on your Virtual Network Address Spaces section on the Configure tab of your virtual network.

Once that is done and you deploy your website (Make sure you deploy in the same datacentre as the virtual network), you should be able to access your site on the internal network.

In my case there was still a problem. This was an internal site but by default, it was accessible via the Cloud Service’s cloudapp.net address. I did the following things to fix this:

First Double click the role in the Cloud Server project of your solution in Visual Studio. Select Endpoints and change the default end point from External to Internal. Then 80 in the private port.

If you deployed now you would no longer be able to access the website via the external cloudapp.net address. But there is a problem, the Cloud Service’s internal firewall will block port 80 making it impossible to connect to via the internal network as well.

To get around the firewall issue, I created a .bat file and added it to the website project and set “Copy to Output Directory” to “Always”. The bat file contained one command:

netsh advfirewall firewall add rule name="HTTP IN" dir=in action=allow service=any enable=yes profile=any localport=80 protocol=tcp

I then modified the ServiceDefinition.csdef file to add an elevated task just after the WebRole element. (It has to be elevated as netsh will require admin privileges)

  <WebRole name="myWebSite" vmsize="Small">
    <Startup>
      <Task commandLine="fwrules.bat" executionContext="elevated" taskType="simple" />
    </Startup>
...

Once this was deployed the site was blocked from the internet but available on the internal network.

2012/12/10

Multiple Database Context Mess and Intercepting writes on a WCF Data Service

Filed under: .NET, Azure, VB.NET — Tags: , , , , , , , — vbmagic @ 3:00 pm

Hi,

Another weekend on hacking code to get the Tyrannt project off the ground. Again I am concentrating on the middle OData web service tier. One of the rules I set myself was to not allow this tier to update the database. These update requests are only meant to be done on the back end tier via messages passed along the Azure Service Bus (ASB).

After an initial hiccup which resulted in my WCF service request falling over with “Not enough memory” (These are hosted in Azure extra small compute instances). I managed to get a working service in the cloud that exposed all my current tables.

Next I wanted to split the tables over multiple data services. I initially achieved this by creating multiple database contexts. This also allowed me to intercept the SaveChanges call in the database context when someone did a Post or Put (Below is my current thinking of how to do this, although this may change when I find it doesn’t work 😉 )

    Public Overrides Function SaveChanges() As Integer
        For Each change In ChangeTracker.Entries
            Dim job As tJob
            Dim entity = change.Entity
            Dim entityType = change.Entity.GetType.Name
            Select Case entityType
                Case "NewsArticle"
                    job = New tjUpdateNewsArticle
                    Dim na As NewsArticle = CType(entity, NewsArticle)
                    '.... Etc
            End Select
        Next

        Return MyBase.SaveChanges()
    End Function

But when it came to trying to actually run this, I kept getting an error saying:

The model backing the 'TyranntSubsetContext' context has changed since the database was created.

After a lot of searching it seemed like some people said this was possible and other said it was not. I decided to change tack and use a single database context that had all my tables in it, but make a duplicate one in my service project which I can use to intercept the saves. (The Back end tier will need normal database access as this will be doing the writes)

Anyway I still needed to expose different tables in different services. And as a nice surprise this time, it was very easy to do.

Here is my DB Context class:

Imports System.Data.Entity
Imports Tyrannt.Model.Email
Imports Tyrannt.Model.News
Imports Tyrannt.Model.Errors
Imports Tyrannt.Model.Membership
Imports Tyrannt.Infrastructure.Jobs
Imports Tyrannt.Infrastructure.Jobs.News

Public Class GlobalDbContext
    Inherits DbContext

    Public Property NewsArticles As DbSet(Of NewsArticle)
    Public Property EmailMessages As DbSet(Of EmailMessage)
    Public Property ErrorMessages As DbSet(Of ErrorMessage)
    Public Property Members As DbSet(Of Member)
    Public Property MemberTypes As DbSet(Of MemberType)

    'Public Overrides Function SaveChanges() As Integer
    '    For Each change In ChangeTracker.Entries
    '        Dim job As tJob
    '        Dim entity = change.Entity
    '        Dim entityType = change.Entity.GetType.Name
    '        Select Case entityType
    '            Case "NewsArticle"
    '                job = New tjUpdateNewsArticle
    '                Dim na As NewsArticle = CType(entity, NewsArticle)

    '        End Select
    '    Next

    '    Return MyBase.SaveChanges()
    'End Function

End Class

And this is my service code (For now I only want to expose the NewsArticles one) :

Imports System.Data.Services
Imports System.Data.Services.Common
Imports System.Linq
Imports System.ServiceModel.Web

Public Class News
    Inherits DataService(Of GlobalDbContext)

    ' This method is called only once to initialize service-wide policies.
    Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)

        ' Expose only the required tables with the relevant access rights
        config.SetEntitySetAccessRule("NewsArticles", EntitySetRights.All)

        ' General settings
        config.UseVerboseErrors = True
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3
    End Sub

End Class

And it worked 🙂

For those curious, here is the service URI:

https://tyranntrpg.org:8443/OData/Codex.svc/

I cannot guarantee this service will always work or still exist in future but it’ll be there while I test client side code.

2012/12/03

Decisions Decisions – Solution Structure and how to get things done

Filed under: .NET, Azure, Learning — Tags: , , , , , , , — vbmagic @ 2:44 pm

I spent most of this weekend, researching different ways to achieve my project. There are certain things that I know I want to do:

Adopt a Three Tier Approach.

  1. Multiple Clients (Including a Website)
  2. A middle service layer that all the clients talk to which can read from the database but not update.
  3. A back end which is the only part of the solution allowed to update the database

The communication between the middle tier and the back end tier will be via the Azure Service bus.

I want the user of the application to be able to log in to the various client using their Windows Account/Google/Facebook ID’s.

With this in mind I was looking into ways to achieve these goals. I was mainly concentrating on what the middle service tier should be.

I wanted something that will make it easy to implement clients on non Microsoft platforms which drew me towards using the new ASP.Net MVC Web API. The downside of this is there is no metadata to describe the service which makes the client much harder to write. After a few discussions with a colleague, they suggested using WCF OData service which should allow making clients easy on the windows side. (Automatic generation of model classes when adding a service reference)

But I’m still open to suggestions from anyone reading this if they think there may be a better way.

The solution structure for the project as it stands now will be:

Tyrannt.Model (Holds the Code First EF Classes)

Tyrannt.Backoffice (Windows Azure Worker Role – The back end tier)

Tyrannt.OData (Web Role – the Middle WCF OData tier)

Tyrannt.Website (First client – will consume the OData service)

I would also like to make use of database migrations that are in Entity Framework 5. Which also brings up another question which it’s been hard to answer. Where is the best place to put the Database context. An easy solution would be to put one in both the Backoffice and OData projects but that means maintaining two separate classes that basically do the same job)

I’ve seen some posts about not having the database context in the same project as the Model classes. I’m trying to work out the best way to do this and still allow database migrations.

Feel free to comment this posts with suggestions ideas or even telling me that I’ve got it all wrong ;-).

2012/11/22

I feel a project coming together

As a way of trying to put all the stuff that I am learning together. I’ve come up with a project. I have been attempting to write a game for ages and have decided to make it using all the new Microsoft technologies. (You may have seen some of the preliminary work resulting in blog posts here.)

So this project will be a web based RPG game (With mobile clients to come later hopefully). It will be hosted in Azure and it will make use of Web Roles, Worker roles, SQL Azure, Azure Service Bus/ACS and Azure Storage. It will be written in Visual Basic .Net.

This is the website: https://www.tyranntrpg.org/

The front page has more details on what is going on and I hope to update the progress regularly here on this blog.

The current site doesn’t do too much as most of the work is going on behind the scenes. But the Codex part will get updates as things progress. In the images section of the codex you can see some of the artwork done by http://www.battleaxegfx.com/
This is one of the images (It will eventually be the Something has gone wrong image)
Dragon and Warrior

This project has been going on for a few years using different tools to create hence the collection of artwork and ideas.

Hopefully this time I’ll get it finished 🙂

2012/11/13

Parsing the HTTPResponse from the Azure Management API

Filed under: .NET, Azure, VB.NET — Tags: , , , , , — vbmagic @ 5:50 pm

Ok, after that last example I ended up pulling what hair I had left in my head out trying to parse the XML that got returned. I have come across this problem before but my memory being what it is I had totally forgotten about it so have written this blog post to help remind myself next time this happens.

I couldn’t seem to be able to get at the elements in the data. I was doing this:

            ' Parse the web response
            responseStream = httpResponse.GetResponseStream
            reader = New StreamReader(responseStream)
            Dim rawOutput As String = reader.ReadToEnd
            Dim xdoc As XDocument = XDocument.Parse(rawOutput)

            Dim serviceOperations = From s In xdoc.Descendants("SubscriptionOperation")
                                    Select s


            For Each s In serviceOperations
                Dim email = s.Descendants("UserEmailAddress").Value
                Dim operation = s.Descendants("OperationName").Value
                Dim opDate = s.Descendants("OperationStartedTime").Value
                Console.WriteLine(String.Format("User: {0} Did: {1} On: {2}", email, operation, opDate))
            Next

And stepping through the code I found that ServiceOperations resolved to nothing. After a couple of hours of poking and prodding and then searching the internet I came across the solution in this post: Fetching Hosting Services Name Using Windows Azure Management API

Namespaces! Memory starts ticking over and I remember hitting this before. So here is the revised code (In full) which will get Subscription details (Basically audit information) from the Management API

Imports System.Net
Imports System.Security.Cryptography.X509Certificates
Imports System.IO
Imports System.Text

Module Module1

    Sub Main()
        ' X.509 certificate variables
        Dim certStore As X509Store
        Dim certCollection As X509Certificate2Collection
        Dim certificate As X509Certificate2

        ' Request and response variables
        Dim httpRequest As HttpWebRequest
        Dim httpResponse As HttpWebResponse

        ' Stream variables
        Dim responseStream As Stream
        Dim reader As StreamReader

        ' URI variable
        Dim requestURI As Uri

        Try

            ' specify time range
            Dim startTime As String = "2012-11-11"
            Dim endTime As String = "2012-11-13"

            ' The ID for the Windows Azure subscription.
            Dim subscriptionId As String = "{Your Subscription}"

            ' The thumbprint for the certificate. This certificate would have been
            ' previously added as a management certificate within the Windows
            ' Azure management portal.
            Dim thumbPrint As String = "{Your Thumbprint}"

            ' Open the certificate store for the current user.
            certStore = New X509Store(StoreName.My, StoreLocation.CurrentUser)
            certStore.Open(OpenFlags.ReadOnly)

            ' Find the certificate with the specified thumbprint
            certCollection = certStore.Certificates.Find(
                X509FindType.FindByThumbprint,
                thumbPrint,
                False)

            ' close the certificate store
            certStore.Close()

            ' Check to see if mat
            If certCollection.Count = 0 Then
                Throw New Exception("No certificate found containing thumbprint " & thumbPrint)
            End If

            ' A matching certificate was found.
            certificate = certCollection(0)
            Console.WriteLine("Using certificate with thumbprint: " & thumbPrint)

            ' create new request
            requestURI = New Uri(
                String.Format("https://management.core.windows.net/{0}/operations?StartTime={1}&EndTime={2}",
                              subscriptionId, startTime, endTime)
                )

            httpRequest = HttpWebRequest.Create(requestURI)

            ' add certificate to requrest
            httpRequest.ClientCertificates.Add(certificate)

            ' Specify the version information in the header
            httpRequest.Headers.Add("x-ms-version", "2012-03-01")
            httpRequest.ContentType = "application/xml"

            ' Make the call using the web request
            httpResponse = httpRequest.GetResponse

            ' Display the response status code
            Console.WriteLine("Response status code: " _
                              & httpResponse.StatusCode)

            ' Display thr request ID returned by windows azure
            If httpResponse.Headers IsNot Nothing Then
                Console.WriteLine("x-ms-request-id: " & httpResponse.Headers("x-ms-request-id"))
            End If

            ' Parse the web response
            responseStream = httpResponse.GetResponseStream
            reader = New StreamReader(responseStream)
            Dim rawOutput As String = reader.ReadToEnd
            Dim ns As XNamespace = "http://schemas.microsoft.com/windowsazure"

            Dim xdoc As XDocument = XDocument.Parse(rawOutput)

            Dim serviceOperations = From s In xdoc.Descendants(ns + "SubscriptionOperation")
                                    Select s


            For Each s In serviceOperations
                Dim email = s.Descendants(ns + "UserEmailAddress").Value
                Dim operation = s.Descendants(ns + "OperationName").Value
                Dim opDate = s.Descendants(ns + "OperationStartedTime").Value
                Console.WriteLine(String.Format("User: {0} Did: {1} On: {2}", email, operation, opDate))
            Next

            httpResponse.Close()
            responseStream.Close()
            reader.Close()
            Console.ReadKey()
        Catch ex As Exception
            Console.WriteLine("Error encountered: " & ex.Message)
            Console.ReadKey()
            System.Environment.Exit(1)
        Finally
            System.Environment.Exit(0)
        End Try
    End Sub

End Module

This can be used as an example to pull audit information from Azure. I hope this helps others not make my silly mistake 😉

P.s. I hope you like the new theme. Thanks to the above blog post (Debugmode.net) for showing it to me. It makes reading source code much better on wider monitors.

A VB example to access the azure management REST API

Filed under: .NET, Azure, VB.NET — Tags: , , , — vbmagic @ 11:54 am

Hi,

This is based on an article in the Code Quick Start from MSDN, Original article is here: Code Quick Start: Create a console application that lists your Windows Azure hosted services

Below is the code which has been converted to VB.net. Everything else in the article is the same apart from creating a VB console program.

Imports System.Net
Imports System.Security.Cryptography.X509Certificates
Imports System.IO

Module Module1

    Sub Main()
        Try

            ' X.509 certificate variables
            Dim certStore As X509Store
            Dim certCollection As X509Certificate2Collection
            Dim certificate As X509Certificate2

            ' Request and response variables
            Dim httpRequest As HttpWebRequest
            Dim httpResponse As HttpWebResponse

            ' Stream variables
            Dim responseStream As Stream
            Dim reader As StreamReader

            ' URI variable
            Dim requestURI As Uri

            ' Specify operation to use for the service management call.
            ' This sample will use the operation for listing the hosted services.
            Dim operation As String = "hostedservices"

            ' The ID for the Windows Azure subscription.
            Dim subscriptionId As String = "{Your Subscription ID}"

            ' The thumbprint for the certificate. This certificate would have been
            ' previously added as a management certificate within the Windows
            ' Azure management portal.
            Dim thumbPrint As String = "{Your Certificate Thumbprint}"

            ' Open the certificate store for the current user.
            certStore = New X509Store(StoreName.My, StoreLocation.CurrentUser)
            certStore.Open(OpenFlags.ReadOnly)

            ' Find the certificate with the specified thumbprint
            certCollection = certStore.Certificates.Find(
                X509FindType.FindByThumbprint,
                thumbPrint,
                False)

            ' close the certificate store
            certStore.Close()

            ' Check to see if mat
            If certCollection.Count = 0 Then
                Throw New Exception("No certificate found containing thumbprint " _
                                    & thumbPrint)
            End If

            ' A matching certificate was found.
            certificate = certCollection(0)
            Console.WriteLine("Using certificate with thumbprint: " & thumbPrint)

            ' create new request
            requestURI = New Uri(
                String.Format("https://management.core.windows.net/{0}/services/{1}",
                              subscriptionId, operation))
            httpRequest = HttpWebRequest.Create(requestURI)

            ' add certificate to requrest
            httpRequest.ClientCertificates.Add(certificate)

            ' Specify the version information in the header
            httpRequest.Headers.Add("x-ms-version", "2011-10-01")

            ' Make the call using the web request
            httpResponse = httpRequest.GetResponse

            ' Display the response status code
            Console.WriteLine("Response status code: " _
                              & httpResponse.StatusCode)

            ' Display thr request ID returned by windows azure
            If httpResponse.Headers IsNot Nothing Then
                Console.WriteLine("x-ms-request-id: " _
                                  & httpResponse.Headers("x-ms-request-id"))
            End If

            ' Parse the web response
            responseStream = httpResponse.GetResponseStream
            reader = New StreamReader(responseStream)
            ' Displa the raw response
            Console.WriteLine("Response output:")
            Console.WriteLine(reader.ReadToEnd)

            ' close the resources no longer needed
            httpResponse.Close()
            responseStream.Close()
            reader.Close()
            Console.ReadKey()
        Catch ex As Exception
            Console.WriteLine("Error encountered: " & ex.Message)
            Console.ReadKey()
            System.Environment.Exit(1)
        Finally
            System.Environment.Exit(0)
        End Try
    End Sub

End Module

2012/07/27

CentOS 6 Azure VM Disk errors

Filed under: Azure, CentOS, VM — Tags: , , , , , — vbmagic @ 2:05 pm

Just a quick post about getting I/O and disk errors on a CentOS 6 VM running in Azure.

I created said VM, did a yum update and then rebooted the VM,

Once it was back up I then started to get lots of I/O errors reported and the file systems were mounted read-only.

After a bit of trial and error plus some web searching I came across this article which had a solution that worked.

http://social.msdn.microsoft.com/Forums/en/WAVirtualMachinesforLinux/thread/0d349334-94ac-478f-b123-cfa970725826

I basically Deleted the VM. Then deleted the Cloud Service associated with the VM. Finally I re-created the VM with the same details from the un-attached disk from the original VM (My Disks part of the Gallery).

Now the file systems are mounted correctly and there are no more IO error messages.

2012/07/19

Taking a IIS pre-generated web service and putting into Azure

Filed under: Azure, Learning, SQL Azure, VB.NET — Tags: , , , , — vbmagic @ 3:11 pm

I had, what I thought, was a simple job to do; but it took over two weeks of discovery to find out it actually was easy, but not quite in the way I was planning to do it.

I had two web services that I needed to host in Azure. For a temporary measure, I create a single Azure instance and this had a simple elevated start up task that installed required run-times and then downloaded 7zip file from Azure storage and then extracted this file.

I then connected to the instance via remote desktop, launched IIS Manager and created the web applications there. I also manually started a back end process.

The next step was to try and automate the deployment of this process using two instances. I moved the required database into SQL Azure which worked fine.

Next I created a new C# Azure project with an ASP.net web role and added the tasks to install the runtime and also looked up the commands required to add the website applications.

I hit a problem that I never really managed to solve where the installation of the C++ 10 runtime would just hang the start-up task. After spending around three days trying to diagnose what had happened I decided to start again from scratch.

I created a new VB Azure project with an ASP.net web role. I added the same task which ran a batch file. This time round the run-times installed with no problem. (I guess I’ll never know what went wrong with that one)

The next part of the script was to download and extract the 7zip archive file. (To download from storage I used the Azure Command Line tools from Rob  Blackwell/Two10 Degrees: https://github.com/RobBlackwell/AzureCommandLineTools)

I then extracted the archive using 7zip command line tools (http://www.7-zip.org/download.html)

It was when I came to run AppCmd.exe to add the extracted web applications, I learned about the order that Tasks etc. are run in Azure. (After a day or so of tracking things down)

The following article helped clarify this a lot. (I’ve borrowed the picture from the article below) http://msdn.microsoft.com/en-us/library/windowsazure/hh127476.aspx

Azure Startup flow chart

Azure Startup flow chart

 

So basically, any start-up tasks would not be able to run scripts that try to modify the website (Like adding the web applications). I abandoned that idea.

Now there is an Elevated Simple task which installs the required run-times and downloads and extracts the files required.

Then there is an Elevated Foreground task which starts the back end process.

All that was left to do was get the web applications (Which were extracted by the Simple Task onto the C: drive)

After a lot more web searching I decided to modify the service definition file for the website and added the virtual applications to this file. (As described in this article: http://msdn.microsoft.com/en-us/library/windowsazure/gg433110.aspx )

I pointed the physical directory to where the application will be extracted to on the C drive of the instance. This caused a build error saying it couldn’t find the directories. I created these directories on the C drive of the machine I was publishing from which allowed the publish to complete.

Unfortunately the deployment got stuck in busy until I deleted it. (Waited a good few hours and tried a couple of times just in case of a “Glitch”).

As a last resort, I extracted the web applications and added the files to the web role’s project folder and then included them into the project. Next I modified the physical directory to a relative directory pointing to the included application directories.

Published and to my great surprise it actually work. Phew!

Took a few weeks but was a great learning process (If a bit frustrating at times 😉 )

Jas

2012/05/24

A great open source library of plug in’s…

Filed under: Azure — vbmagic @ 2:09 pm

A great open source library of plug-in’s that should hopefully make life easier in Azure to make use of third party software or currently unsupported components like Classic ASP.

Richard Astbury's Blog

tl;dr

An open source library of plugins installed with a command line tool (a package manager). Once a plugin is installed, it can be easily packaged with an Azure deployment to install application dependencies on a Web or Worker role.

http://richorama.github.com/AzurePluginLibrary/

Watch a screen cast demonstration

Background

One of the key strengths of Windows Azure, is the Platform as a Service offering. Why would you want to patch an operating system, manage the deployment of your application, and check the health of your infrastructure? It’s better left to someone else (Microsoft) so you can focus on your application. However, the pitfall is when your application depends on something extra being installed or configured on the machine.

There are a few ways for installing 3rd party components on an Azure instance. This blog post has a good summary of the options.

In summary, start-up tasks are the best mechanism available for…

View original post 327 more words

2012/03/27

atomus – Solution for sharing session data in the Azure Cloud between JBoss/Tomcat instances

Filed under: Azure — Tags: , , , — vbmagic @ 2:48 pm

Another problem I was having was solved using this solution. I needed to share session data for an application in the Azure cloud between multiple JBoss instances. Due to issues where clustering of JBoss was not a viable solution for the application. I came across this solution thanks to a post by Rob Blackwell (Java on the Windows Azure Cloud).

The solution just required a minor configuration change and adding of a few .jar files in JBoss and it just worked. I’ve not tested this with a large scale out of instances but for my purposes it did exactly what I needed.

atomus can be obtained from the following URL.

https://github.com/atomus/TomcatAzureSessionManager

Older Posts »

Blog at WordPress.com.